Merge remote-tracking branch 'origin/master'
authorKirill Likhodedov <Kirill.Likhodedov@jetbrains.com>
Fri, 27 Jan 2012 14:28:11 +0000 (18:28 +0400)
committerKirill Likhodedov <Kirill.Likhodedov@jetbrains.com>
Fri, 27 Jan 2012 14:28:11 +0000 (18:28 +0400)
284 files changed:
.idea/libraries/Netty.xml
images/src/org/intellij/images/util/ImageInfoReader.java
java/compiler/impl/src/com/intellij/compiler/CompileServerManager.java
java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
java/compiler/impl/src/com/intellij/compiler/impl/GenericCompilerRunner.java
java/compiler/impl/src/com/intellij/openapi/compiler/generic/SingleTargetCompilerInstance.java [deleted file]
java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileCompileItem.java
java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskProvider.java
java/debugger/impl/src/com/intellij/debugger/engine/RequestHint.java
java/execution/impl/src/com/intellij/execution/impl/DefaultJavaProgramRunner.java
java/execution/openapi/src/com/intellij/execution/JavaExecutionUtil.java
java/java-impl/src/com/intellij/psi/impl/file/PsiPackageImplementationHelperImpl.java
java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java
java/java-impl/src/com/intellij/unscramble/UnscrambleDialog.form
java/java-psi-impl/src/com/intellij/codeInsight/ExceptionUtil.java
java/java-psi-impl/src/com/intellij/lang/java/parser/DeclarationParser.java
java/java-psi-impl/src/com/intellij/lang/java/parser/ExpressionParser.java
java/java-psi-impl/src/com/intellij/lang/java/parser/JavaParserUtil.java
java/java-psi-impl/src/com/intellij/lang/java/parser/ReferenceParser.java
java/java-psi-impl/src/com/intellij/lang/java/parser/StatementParser.java
java/java-psi-impl/src/messages/JavaErrorMessages.properties
java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/TryWithResources.java
java/java-tests/testData/psi/parser-partial/expressions/Binary2.txt [new file with mode: 0644]
java/java-tests/testData/psi/parser-partial/expressions/Binary3.txt [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/lang/java/lexer/JavaLexerTest.java
java/java-tests/testSrc/com/intellij/lang/java/parser/partial/ExpressionParserTest.java
java/openapi/src/com/intellij/psi/util/ClassUtil.java
java/openapi/src/com/intellij/ui/classFilter/ClassFilterEditor.java
java/testFramework/src/com/intellij/testFramework/fixtures/DefaultLightProjectDescriptor.java
jps/jps-builders/src/defaultLogConfig.xml [new file with mode: 0644]
jps/jps-builders/src/org/jetbrains/jps/incremental/Builder.java
jps/jps-builders/src/org/jetbrains/jps/incremental/BuilderRegistry.java
jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java
jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleLevelBuilder.java [new file with mode: 0644]
jps/jps-builders/src/org/jetbrains/jps/incremental/ProjectLevelBuilder.java [new file with mode: 0644]
jps/jps-builders/src/org/jetbrains/jps/incremental/groovy/GroovyBuilder.java
jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java
jps/jps-builders/src/org/jetbrains/jps/incremental/resources/ResourcesBuilder.java [moved from jps/jps-builders/src/org/jetbrains/jps/incremental/resourses/ResourcesBuilder.java with 97% similarity]
jps/jps-builders/src/org/jetbrains/jps/server/Server.java
jps/model/src/org/jetbrains/ether/dependencyView/DependencyContext.java
jps/model/src/org/jetbrains/ether/dependencyView/Logger.java
jps/model/src/org/jetbrains/ether/dependencyView/Mappings.java
lib/netty-3.2.5.Final.jar [deleted file]
lib/netty-3.3.0.Final.jar [new file with mode: 0644]
lib/required_for_dist.txt
lib/src/netty-3.2.5.Final-sources.jar [deleted file]
lib/src/netty-3.3.0.Final-sources.jar [new file with mode: 0644]
platform/icons/src/actions/move-to-button-top.png [new file with mode: 0644]
platform/icons/src/actions/move-to-button.png [new file with mode: 0644]
platform/lang-api/src/com/intellij/execution/DefaultExecutionResult.java
platform/lang-api/src/com/intellij/execution/ui/actions/BaseViewAction.java
platform/lang-api/src/com/intellij/execution/ui/layout/CellTransform.java
platform/lang-api/src/com/intellij/execution/ui/layout/GridCell.java
platform/lang-api/src/com/intellij/execution/ui/layout/Tab.java
platform/lang-api/src/com/intellij/execution/ui/layout/View.java
platform/lang-api/src/com/intellij/lang/cacheBuilder/DefaultWordsScanner.java
platform/lang-impl/src/com/intellij/codeInsight/AutoPopupController.java
platform/lang-impl/src/com/intellij/codeInsight/documentation/DocumentationComponent.java
platform/lang-impl/src/com/intellij/execution/impl/ExecutionManagerImpl.java
platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java
platform/lang-impl/src/com/intellij/execution/ui/layout/actions/AttachCellAction.java [deleted file]
platform/lang-impl/src/com/intellij/execution/ui/layout/actions/CloseViewAction.java
platform/lang-impl/src/com/intellij/execution/ui/layout/actions/DetachCellAction.java [deleted file]
platform/lang-impl/src/com/intellij/execution/ui/layout/actions/MinimizeViewAction.java
platform/lang-impl/src/com/intellij/execution/ui/layout/actions/MoveToGridAction.java [deleted file]
platform/lang-impl/src/com/intellij/execution/ui/layout/actions/MoveToTabAction.java [deleted file]
platform/lang-impl/src/com/intellij/execution/ui/layout/impl/AbstractTab.java
platform/lang-impl/src/com/intellij/execution/ui/layout/impl/DockableGridContainerFactory.java [new file with mode: 0644]
platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridCellImpl.java
platform/lang-impl/src/com/intellij/execution/ui/layout/impl/GridImpl.java
platform/lang-impl/src/com/intellij/execution/ui/layout/impl/JBRunnerTabs.java [new file with mode: 0644]
platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerContentUi.java
platform/lang-impl/src/com/intellij/execution/ui/layout/impl/RunnerLayout.java
platform/lang-impl/src/com/intellij/execution/ui/layout/impl/TabImpl.java
platform/lang-impl/src/com/intellij/execution/ui/layout/impl/ViewContextEx.java
platform/lang-impl/src/com/intellij/execution/ui/layout/impl/ViewImpl.java
platform/lang-impl/src/com/intellij/ide/actions/GotoRelatedFileAction.java
platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateManagerImpl.java
platform/lang-impl/src/com/intellij/ide/todo/TodoTreeBuilder.java
platform/lang-impl/src/com/intellij/ide/util/FileStructurePopup.java
platform/lang-impl/src/com/intellij/psi/stubs/SerializedStubTree.java
platform/platform-api/src/com/intellij/ide/util/treeView/AbstractTreeUi.java
platform/platform-api/src/com/intellij/notification/Notification.java
platform/platform-api/src/com/intellij/ui/TableScrollingUtil.java
platform/platform-api/src/com/intellij/ui/docking/DockContainer.java
platform/platform-api/src/com/intellij/ui/docking/DockContainerFactory.java
platform/platform-api/src/com/intellij/ui/tabs/TabsListener.java
platform/platform-api/src/com/intellij/ui/tabs/impl/ActionPanel.java
platform/platform-api/src/com/intellij/ui/tabs/impl/DragHelper.java
platform/platform-api/src/com/intellij/ui/tabs/impl/JBTabsImpl.java
platform/platform-api/src/com/intellij/ui/tabs/impl/TabLabel.java
platform/platform-impl/src/com/intellij/ide/actions/UndoRedoAction.java
platform/platform-impl/src/com/intellij/idea/SocketLock.java
platform/platform-impl/src/com/intellij/idea/StartupUtil.java
platform/platform-impl/src/com/intellij/notification/EventLog.java
platform/platform-impl/src/com/intellij/notification/impl/NotificationsManagerImpl.java
platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java
platform/platform-impl/src/com/intellij/openapi/command/impl/CommandProcessorImpl.java
platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/DockableEditorContainerFactory.java
platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/DockableEditorTabbedContainer.java
platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java
platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/FileEditorManagerImpl.java
platform/platform-impl/src/com/intellij/openapi/ui/impl/GlassPaneDialogWrapperPeer.java
platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/LocalFileSystemBase.java
platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/PersistentFS.java
platform/platform-impl/src/com/intellij/ui/docking/impl/DockManagerImpl.java
platform/platform-resources-en/src/messages/ActionsBundle.properties
platform/platform-resources-en/src/messages/ExecutionBundle.properties
platform/platform-resources-en/src/misc/registry.properties
platform/platform-resources/src/idea/LangActions.xml
platform/platform-tests/testSrc/com/intellij/notification/EventLogTest.groovy [new file with mode: 0644]
platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/FileDocumentManagerImplTest.java [new file with mode: 0644]
platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/IdeDocumentHistoryTest.java [new file with mode: 0644]
platform/platform-tests/testSrc/com/intellij/openapi/fileEditor/LoadTextUtilTest.java [new file with mode: 0644]
platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerNodeDescriptor.java
platform/smRunner/src/com/intellij/execution/testframework/sm/runner/SMTRunnerTreeBuilder.java
platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java
platform/testFramework/src/com/intellij/mock/Mock.java [new file with mode: 0644]
platform/testFramework/src/com/intellij/mock/MockCommandProcessor.java [new file with mode: 0644]
platform/testFramework/src/com/intellij/mock/MockVirtualFile.java
platform/testFramework/src/com/intellij/testFramework/PlatformTestCase.java
platform/testRunner/src/com/intellij/execution/testframework/TestConsoleProperties.java
platform/testRunner/src/com/intellij/execution/testframework/TestFrameworkRunningModel.java
platform/testRunner/src/com/intellij/execution/testframework/ToolbarPanel.java
platform/testRunner/src/com/intellij/execution/testframework/ui/AbstractTestTreeBuilder.java
platform/testRunner/src/com/intellij/execution/testframework/ui/BaseTestProxyNodeDescriptor.java [new file with mode: 0644]
platform/util/src/com/intellij/AbstractBundle.java
platform/util/src/com/intellij/openapi/util/io/BufferExposingByteArrayInputStream.java
platform/util/src/com/intellij/openapi/util/io/BufferExposingByteArrayOutputStream.java
platform/util/src/com/intellij/openapi/util/io/FileSystemUtil.java
platform/util/src/com/intellij/openapi/util/io/FileUtil.java
platform/util/src/com/intellij/util/io/IntToIntBtree.java
platform/util/src/com/intellij/util/io/PersistentBTreeEnumerator.java
platform/util/src/com/intellij/util/io/PersistentHashMap.java
platform/util/src/com/intellij/util/io/PersistentHashMapValueStorage.java
platform/util/src/com/intellij/util/io/UnsyncByteArrayInputStream.java [new file with mode: 0644]
platform/util/src/com/intellij/util/io/UnsyncByteArrayOutputStream.java [new file with mode: 0644]
platform/util/src/com/intellij/util/io/storage/AbstractStorage.java
platform/vcs-api/src/com/intellij/openapi/vcs/VcsVFSListener.java
platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsContentAnnotationConfigurable.java
platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java
plugins/InspectionGadgets/src/META-INF/plugin.xml
plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties
plugins/InspectionGadgets/src/com/siyeh/ig/performance/StringBufferReplaceableByStringInspection.java [deleted file]
plugins/InspectionGadgets/src/com/siyeh/ig/style/StringBufferReplaceableByStringInspection.java [new file with mode: 0644]
plugins/InspectionGadgets/src/com/siyeh/ig/style/VariableIsModifiedVisitor.java [moved from plugins/InspectionGadgets/src/com/siyeh/ig/performance/VariableIsModifiedVisitor.java with 73% similarity]
plugins/InspectionGadgets/src/inspectionDescriptions/StringBufferReplaceableByString.html
plugins/InspectionGadgets/test/com/siyeh/igtest/performance/StringBufferReplaceableByStringInspection.java [deleted file]
plugins/InspectionGadgets/test/com/siyeh/igtest/performance/string_buffer_replaceable_by_string/StringBufferReplaceableByString.java [new file with mode: 0644]
plugins/InspectionGadgets/test/com/siyeh/igtest/performance/string_buffer_replaceable_by_string/expected.xml [new file with mode: 0644]
plugins/InspectionGadgets/testsrc/com/siyeh/ig/style/StringBufferReplaceableByStringInspectionTest.java [new file with mode: 0644]
plugins/android/resources/messages/AndroidBundle.properties
plugins/android/src/org/jetbrains/android/actions/CreateResourceDialog.form
plugins/android/src/org/jetbrains/android/actions/CreateXmlResourceDialog.form [new file with mode: 0644]
plugins/android/src/org/jetbrains/android/actions/CreateXmlResourceDialog.java [new file with mode: 0644]
plugins/android/src/org/jetbrains/android/dom/converters/ResourceReferenceConverter.java
plugins/android/src/org/jetbrains/android/inspections/lint/AddMissingPrefixQuickFix.java [new file with mode: 0644]
plugins/android/src/org/jetbrains/android/inspections/lint/AndroidAddStringResourceQuickFix.java [new file with mode: 0644]
plugins/android/src/org/jetbrains/android/inspections/lint/AndroidLintExternalAnnotator.java
plugins/android/src/org/jetbrains/android/inspections/lint/AndroidLintGlobalInspectionContext.java
plugins/android/src/org/jetbrains/android/inspections/lint/AndroidLintInspectionBase.java
plugins/android/src/org/jetbrains/android/inspections/lint/AndroidLintInspectionToolProvider.java
plugins/android/src/org/jetbrains/android/inspections/lint/AndroidLintQuickFix.java [new file with mode: 0644]
plugins/android/src/org/jetbrains/android/inspections/lint/AndroidLintUtil.java [new file with mode: 0644]
plugins/android/src/org/jetbrains/android/inspections/lint/ConvertToDpQuickFix.java [new file with mode: 0644]
plugins/android/src/org/jetbrains/android/inspections/lint/FakeNode.java [new file with mode: 0644]
plugins/android/src/org/jetbrains/android/inspections/lint/InefficientWeightQuickFix.java [new file with mode: 0644]
plugins/android/src/org/jetbrains/android/inspections/lint/IntellijLintClient.java
plugins/android/src/org/jetbrains/android/inspections/lint/IntellijLintConfiguration.java [new file with mode: 0644]
plugins/android/src/org/jetbrains/android/inspections/lint/RemoveAttributeQuickFix.java [new file with mode: 0644]
plugins/android/src/org/jetbrains/android/inspections/lint/RemoveUselessViewQuickFix.java [new file with mode: 0644]
plugins/android/src/org/jetbrains/android/inspections/lint/SetAttributeQuickFix.java [new file with mode: 0644]
plugins/android/src/org/jetbrains/android/inspections/lint/SetScrollViewSizeQuickFix.java [new file with mode: 0644]
plugins/android/src/org/jetbrains/android/inspections/lint/TypographyQuickFix.java [new file with mode: 0644]
plugins/android/src/org/jetbrains/android/intentions/AndroidAddStringResourceAction.java
plugins/android/src/org/jetbrains/android/resourceManagers/LocalResourceManager.java
plugins/android/src/org/jetbrains/android/uipreview/DeviceConfiguratorPanel.java
plugins/android/src/org/jetbrains/android/util/AndroidResourceUtil.java
plugins/android/testData/addStringRes/Class10_after.java
plugins/android/testData/addStringRes/Class11_after.java
plugins/android/testData/addStringRes/Class12_after.java
plugins/android/testData/addStringRes/Class13.java
plugins/android/testData/addStringRes/Class13_after.java
plugins/android/testData/addStringRes/Class14.java
plugins/android/testData/addStringRes/Class1_after.java
plugins/android/testData/addStringRes/Class2_after.java
plugins/android/testData/addStringRes/Class3_after.java
plugins/android/testData/addStringRes/Class4_after.java
plugins/android/testData/addStringRes/Class5_after.java
plugins/android/testData/addStringRes/Class6_after.java
plugins/android/testData/addStringRes/Class7_after.java
plugins/android/testData/addStringRes/Class8.java
plugins/android/testData/addStringRes/Class8_after.java
plugins/android/testData/addStringRes/Class9.java
plugins/android/testData/addStringRes/Class9_after.java
plugins/android/testData/addStringRes/ClassEscape_after.java
plugins/android/testData/addStringRes/fromLayout.xml [new file with mode: 0644]
plugins/android/testData/addStringRes/fromLayout1.xml [new file with mode: 0644]
plugins/android/testData/addStringRes/fromLayout_after.xml [new file with mode: 0644]
plugins/android/testData/addStringRes/fromManifest.xml [new file with mode: 0644]
plugins/android/testData/addStringRes/fromManifest1.xml [new file with mode: 0644]
plugins/android/testData/addStringRes/fromManifest1_after.xml [new file with mode: 0644]
plugins/android/testData/addStringRes/fromManifest2.xml [new file with mode: 0644]
plugins/android/testData/lint/adapterViewChildren.xml [new file with mode: 0644]
plugins/android/testData/lint/baselineWeights.xml [new file with mode: 0644]
plugins/android/testData/lint/baselineWeights_after.xml [new file with mode: 0644]
plugins/android/testData/lint/contentDescription.xml [new file with mode: 0644]
plugins/android/testData/lint/contentDescription1.xml [new file with mode: 0644]
plugins/android/testData/lint/contentDescription_after.xml [new file with mode: 0644]
plugins/android/testData/lint/convertToDp.xml [new file with mode: 0644]
plugins/android/testData/lint/convertToDp_after.xml [new file with mode: 0644]
plugins/android/testData/lint/duplicatedIds.xml [new file with mode: 0644]
plugins/android/testData/lint/editText.xml [new file with mode: 0644]
plugins/android/testData/lint/editText_after.xml [new file with mode: 0644]
plugins/android/testData/lint/exportedService.xml [new file with mode: 0644]
plugins/android/testData/lint/exportedService_after.xml [new file with mode: 0644]
plugins/android/testData/lint/hardcodedQuickfix.xml [new file with mode: 0644]
plugins/android/testData/lint/hardcodedQuickfix1.xml [new file with mode: 0644]
plugins/android/testData/lint/hardcodedQuickfix1_after.xml [new file with mode: 0644]
plugins/android/testData/lint/hardcodedQuickfix_after.xml [new file with mode: 0644]
plugins/android/testData/lint/inefficientWeight.xml [new file with mode: 0644]
plugins/android/testData/lint/inefficientWeight_after.xml [new file with mode: 0644]
plugins/android/testData/lint/missingPrefix.xml [new file with mode: 0644]
plugins/android/testData/lint/missingPrefix1.xml [new file with mode: 0644]
plugins/android/testData/lint/missingPrefix1_after.xml [new file with mode: 0644]
plugins/android/testData/lint/missingPrefix_after.xml [new file with mode: 0644]
plugins/android/testData/lint/obsoleteLayoutParams.xml [new file with mode: 0644]
plugins/android/testData/lint/obsoleteLayoutParams_after.xml [new file with mode: 0644]
plugins/android/testData/lint/scrollViewChildren.xml [new file with mode: 0644]
plugins/android/testData/lint/scrollViewSize.xml [new file with mode: 0644]
plugins/android/testData/lint/scrollViewSize_after.xml [new file with mode: 0644]
plugins/android/testData/lint/typographyDashes.xml [new file with mode: 0644]
plugins/android/testData/lint/typographyDashes_after.xml [new file with mode: 0644]
plugins/android/testData/lint/typographyQuotes.xml [new file with mode: 0644]
plugins/android/testData/lint/typographyQuotes_after.xml [new file with mode: 0644]
plugins/android/testData/lint/uselessLeaf.xml [new file with mode: 0644]
plugins/android/testData/lint/uselessLeaf_after.xml [new file with mode: 0644]
plugins/android/testData/lint/uselessParent.xml [new file with mode: 0644]
plugins/android/testSrc/org/jetbrains/android/AndroidLintTest.java [new file with mode: 0644]
plugins/android/testSrc/org/jetbrains/android/intentions/AndroidAddStringResourceActionTest.java
plugins/devkit/resources/META-INF/plugin.xml
plugins/devkit/src/actions/ToggleHighlightingMarkupAction.java [moved from plugins/devkit/src/actions/GenerateHighlightingMarkupAction.java with 53% similarity]
plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyCodeFragmentFactory.java
plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/AlignmentProvider.java [new file with mode: 0644]
plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GeeseUtil.java
plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlock.java
plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyBlockGenerator.java
plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/GroovyFormattingModelBuilder.java
plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/MethodCallWithoutQualifierBlock.java
plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java
plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/params/GrParameterImpl.java
plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/members/GrMethodBaseImpl.java
plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/MvcModuleStructureSynchronizer.java
plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/projectView/MvcProjectViewPane.java
plugins/groovy/src/org/jetbrains/plugins/groovy/mvc/projectView/MvcToolWindowDescriptor.java
plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTest.groovy
plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTestCase.java
plugins/groovy/test/org/jetbrains/plugins/groovy/lang/formatter/FormatterTest.java
plugins/groovy/testdata/groovy/formatter/geese8.test [new file with mode: 0644]
plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java
plugins/junit/src/com/intellij/execution/junit/TestMethod.java
plugins/junit/src/com/intellij/execution/junit/TestsPattern.java
plugins/junit/src/com/intellij/execution/junit2/ui/model/TestProxyDescriptor.java
plugins/junit/src/com/intellij/execution/junit2/ui/model/TestTreeBuilder.java
plugins/maven/src/main/java/org/jetbrains/idea/maven/execution/MavenRunnerParametersConfigurable.java
plugins/properties/src/com/intellij/lang/properties/xml/XmlPropertiesIndex.java
plugins/tasks/jira-connector/jira-connector.iml
plugins/tasks/jira-connector/src/main/java/com/intellij/tasks/jira/HttpClientTransport.java [deleted file]
plugins/tasks/tasks-core/src/com/intellij/tasks/trac/TracRepository.java
plugins/tasks/tasks-tests/tasks-tests.iml
plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/TracIntegrationTest.java [new file with mode: 0644]
plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfiguration.java
plugins/testng/src/com/theoryinpractice/testng/configuration/TestNGConfigurationEditor.java
plugins/testng/src/com/theoryinpractice/testng/model/TestNodeDescriptor.java
plugins/testng/src/com/theoryinpractice/testng/model/TestTreeBuilder.java
plugins/testng/src/com/theoryinpractice/testng/ui/TestNGResults.java
plugins/ui-designer/src/com/intellij/uiDesigner/GeneralConfigurable.form
plugins/ui-designer/src/com/intellij/uiDesigner/inspections/NoLabelForInspection.java
plugins/ui-designer/src/messages/UIDesignerBundle.properties
xml/dom-impl/src/com/intellij/util/xml/DomFileIndex.java
xml/dom-openapi/src/com/intellij/util/xml/model/impl/DomModelImpl.java
xml/impl/src/com/intellij/xml/index/XmlNamespaceIndex.java
xml/impl/src/com/intellij/xml/index/XmlTagNamesIndex.java
xml/relaxng/src/org/intellij/plugins/relaxNG/compact/RncParserDefinition.java

index ef0ce7ca25db08b2363fc1ec6829851f8a847525..c5b98b3964c17d3638a1b6cc4fb7c4a5dfde07c4 100644 (file)
@@ -1,11 +1,11 @@
 <component name="libraryTable">
   <library name="Netty">
     <CLASSES>
-      <root url="jar://$PROJECT_DIR$/lib/netty-3.2.5.Final.jar!/" />
+      <root url="jar://$PROJECT_DIR$/lib/netty-3.3.0.Final.jar!/" />
     </CLASSES>
     <JAVADOC />
     <SOURCES>
-      <root url="jar://$PROJECT_DIR$/lib/src/netty-3.2.5.Final-sources.jar!/" />
+      <root url="jar://$PROJECT_DIR$/lib/src/netty-3.3.0.Final-sources.jar!/" />
     </SOURCES>
   </library>
 </component>
\ No newline at end of file
index 1c809bbba28f3ee99d8baf579d5bd4d42c9e303c..7dd764faa32865e9a9f32745f69d35040765be5a 100644 (file)
@@ -16,6 +16,7 @@
 package org.intellij.images.util;
 
 import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.util.io.UnsyncByteArrayInputStream;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -65,7 +66,7 @@ public class ImageInfoReader {
 
   @Nullable
   private static Info read(@NotNull final byte[] data) {
-    final DataInputStream is = new DataInputStream(new ByteArrayInputStream(data));
+    final DataInputStream is = new DataInputStream(new UnsyncByteArrayInputStream(data));
     try {
       return readFileData(is);
     }
index 025bbfbe206babe729f1eed605e5a36f00dd067c..fe90cf55f56269fa0131dee535f4729eba9014ed 100644 (file)
@@ -62,7 +62,9 @@ import org.jetbrains.jps.server.Server;
 import javax.tools.JavaCompiler;
 import javax.tools.ToolProvider;
 import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.*;
 import java.util.concurrent.Future;
 import java.util.concurrent.RunnableFuture;
@@ -73,8 +75,10 @@ import java.util.concurrent.TimeUnit;
  *         Date: 9/6/11
  */
 public class CompileServerManager implements ApplicationComponent{
-  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.JpsServerManager");
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.CompileServerManager");
   private static final String COMPILE_SERVER_SYSTEM_ROOT = "compile-server";
+  private static final String LOGGER_CONFIG = "log.xml";
+  private static final String DEFAULT_LOGGER_CONFIG = "defaultLogConfig.xml";
   private volatile OSProcessHandler myProcessHandler;
   private final File mySystemDirectory;
   private volatile CompileServerClient myClient = new CompileServerClient();
@@ -272,7 +276,7 @@ public class CompileServerManager implements ApplicationComponent{
           return true;
         }
       };
-      final Ref<String> serverStartMessage = new Ref<String>(null);
+      final StringBuilder serverStartMessage = new StringBuilder();
       final Semaphore semaphore  = new Semaphore();
       semaphore.down();
       processHandler.addProcessListener(new ProcessAdapter() {
@@ -298,8 +302,11 @@ public class CompileServerManager implements ApplicationComponent{
               if (text != null) {
                 if (text.contains(Server.SERVER_SUCCESS_START_MESSAGE) || text.contains(Server.SERVER_ERROR_START_MESSAGE)) {
                   processHandler.removeProcessListener(this);
-                  serverStartMessage.set(text);
                 }
+                if (serverStartMessage.length() > 0) {
+                  serverStartMessage.append("\n");
+                }
+                serverStartMessage.append(text);
               }
             }
             finally {
@@ -311,8 +318,8 @@ public class CompileServerManager implements ApplicationComponent{
       processHandler.startNotify();
       semaphore.waitFor();
 
-      final String startupMsg = serverStartMessage.get();
-      if (startupMsg == null || !startupMsg.contains(Server.SERVER_SUCCESS_START_MESSAGE)) {
+      final String startupMsg = serverStartMessage.toString();
+      if (!startupMsg.contains(Server.SERVER_SUCCESS_START_MESSAGE)) {
         throw new Exception("Server startup failed: " + startupMsg);
       }
 
@@ -462,14 +469,43 @@ public class CompileServerManager implements ApplicationComponent{
 
     final File workDirectory = new File(mySystemDirectory, COMPILE_SERVER_SYSTEM_ROOT);
     workDirectory.mkdirs();
+    ensureLogConfigExists(workDirectory);
 
     cmdLine.addParameter(FileUtil.toSystemIndependentName(workDirectory.getPath()));
 
     cmdLine.setWorkDirectory(workDirectory);
 
+
     return cmdLine.createProcess();
   }
 
+  private static void ensureLogConfigExists(File workDirectory) {
+    final File logConfig = new File(workDirectory, LOGGER_CONFIG);
+    if (!logConfig.exists()) {
+      FileUtil.createIfDoesntExist(logConfig);
+      try {
+        final InputStream in = Server.class.getResourceAsStream("/" + DEFAULT_LOGGER_CONFIG);
+        if (in != null) {
+          try {
+            final FileOutputStream out = new FileOutputStream(logConfig);
+            try {
+              FileUtil.copy(in, out);
+            }
+            finally {
+              out.close();
+            }
+          }
+          finally {
+            in.close();
+          }
+        }
+      }
+      catch (IOException e) {
+        LOG.error(e);
+      }
+    }
+  }
+
   public void shutdownServer() {
     shutdownServer(myClient, myProcessHandler);
   }
index d836d57763029b5cf51e931fc94763c7a87302e3..38a4c9a8c71610a40c3d7a96b9da4f56fb66c4bc 100644 (file)
@@ -966,7 +966,8 @@ public class CompileDriver {
       boolean didSomething = false;
 
       final CompilerManager compilerManager = CompilerManager.getInstance(myProject);
-      GenericCompilerRunner runner = new GenericCompilerRunner(context, myCompilerFilter, compilerManager, isRebuild, onlyCheckStatus);
+      GenericCompilerRunner runner = new GenericCompilerRunner(context, isRebuild, onlyCheckStatus,
+                                                               compilerManager.getCompilers(GenericCompiler.class, myCompilerFilter));
       try {
         didSomething |= generateSources(compilerManager, context, forceCompile, onlyCheckStatus);
 
index e6e5cc500daafda8f5a445814217ef2868fff28a..f03a286173233ac9d1c00e4cbdad4708553f198c 100644 (file)
@@ -53,14 +53,12 @@ public class GenericCompilerRunner {
   private final Project myProject;
 
   public GenericCompilerRunner(CompileContext context,
-                               CompilerFilter compilerFilter,
-                               CompilerManager compilerManager,
                                boolean forceCompile,
-                               boolean onlyCheckStatus) {
+                               boolean onlyCheckStatus, final GenericCompiler[] compilers) {
     myContext = context;
     myForceCompile = forceCompile;
     myOnlyCheckStatus = onlyCheckStatus;
-    myCompilers = compilerManager.getCompilers(GenericCompiler.class, compilerFilter);
+    myCompilers = compilers;
     myProject = myContext.getProject();
   }
 
@@ -69,7 +67,7 @@ public class GenericCompilerRunner {
     try {
       for (GenericCompiler<?,?,?> compiler : myCompilers) {
         if (compiler.getOrderPlace().equals(place)) {
-          didSomething = invokeCompiler(compiler);
+          didSomething |= invokeCompiler(compiler);
         }
       }
     }
diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/SingleTargetCompilerInstance.java b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/SingleTargetCompilerInstance.java
deleted file mode 100644 (file)
index f2e4dd3..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2000-2010 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.openapi.compiler.generic;
-
-import com.intellij.openapi.compiler.CompileContext;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * @author nik
- */
-public abstract class SingleTargetCompilerInstance<Item extends CompileItem<K,S,O>, K,S, O> extends
-                                                                                            GenericCompilerInstance<BuildTarget, Item, K, S, O> {
-  protected SingleTargetCompilerInstance(CompileContext context) {
-    super(context);
-  }
-
-  @NotNull
-  @Override
-  public List<BuildTarget> getAllTargets() {
-    return Collections.singletonList(BuildTarget.DEFAULT);
-  }
-
-  @NotNull
-  @Override
-  public List<BuildTarget> getSelectedTargets() {
-    return getAllTargets();
-  }
-
-  @Override
-  public void processObsoleteTarget(@NotNull String targetId, @NotNull List<GenericCompilerCacheState<K, S, O>> obsoleteItems) {
-  }
-}
index 03a14bd0d63cfb7bd4ed78eb080e4f013c225fa8..b1e5394fc60d5e9f149bd7c8fb5cbb61bd116f8e 100644 (file)
@@ -16,8 +16,6 @@
 package com.intellij.openapi.compiler.generic;
 
 import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.io.EnumeratorStringDescriptor;
-import com.intellij.util.io.KeyDescriptor;
 import org.jetbrains.annotations.NotNull;
 
 /**
index 3b0e586020f2c522549bd316de267c3125a20af4..ee2315e3a0464e9a5e62dedeb0fb5acd828517fb 100644 (file)
@@ -99,6 +99,7 @@ public class BuildArtifactsBeforeRunTaskProvider extends BeforeRunTaskProvider<B
   }
 
   public BuildArtifactsBeforeRunTask createTask(RunConfiguration runConfiguration) {
+    if (myProject.isDefault()) return null;
     return new BuildArtifactsBeforeRunTask(myProject);
   }
 
index 08bafc3e50cd4ff963fafeac80581baf8ce53cc9..1a94cbc25ec41f0858c2add6f0dffe36218c8759 100644 (file)
@@ -61,9 +61,16 @@ public class RequestHint {
     private boolean myMethodExecuted;
 
     public SmartStepFilter(PsiMethod psiMethod) {
-      myDeclaringClassName = JVMNameUtil.getJVMQualifiedName(psiMethod.getContainingClass());
-      myTargetMethodName = psiMethod.isConstructor()? "<init>" : psiMethod.getName();
-      myTargetMethodSignature = JVMNameUtil.getJVMSignature(psiMethod);
+      this(JVMNameUtil.getJVMQualifiedName(psiMethod.getContainingClass()),
+           psiMethod.isConstructor()? "<init>" : psiMethod.getName(),
+           JVMNameUtil.getJVMSignature(psiMethod));
+    }
+
+    public SmartStepFilter(@NotNull JVMName declaringClassName, @NonNls String targetMethodName,
+                           @NotNull JVMName targetMethodSignature) {
+      myDeclaringClassName = declaringClassName;
+      myTargetMethodName = targetMethodName;
+      myTargetMethodSignature = targetMethodSignature;
     }
 
     public String getTargetMethodName() {
index 6707b6ab50104b8dd0bf7d30d9cee6afe5b8733e..566719bce954b259b79ffa356baeabc083558756 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2012 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -108,6 +108,7 @@ public class DefaultJavaProgramRunner extends JavaPatchableProgramRunner {
     if (consoleComponent != null) {
       controlBreakAction.registerCustomShortcutSet(controlBreakAction.getShortcutSet(), consoleComponent);
       final ProcessHandler processHandler = executionResult.getProcessHandler();
+      assert processHandler != null : executionResult;
       processHandler.addProcessListener(new ProcessAdapter() {
         public void processTerminated(final ProcessEvent event) {
           processHandler.removeProcessListener(this);
index 3239824d4adad7db81e806da4fc960de90098701..89cc65ebeeafd5c7e6a8a8fc20a0724250c12ddb 100644 (file)
@@ -30,6 +30,7 @@ import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.*;
 import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.util.ClassUtil;
 import com.intellij.psi.util.PsiClassUtil;
 import com.intellij.psi.util.PsiTreeUtil;
 import org.jetbrains.annotations.NotNull;
@@ -106,14 +107,7 @@ public class JavaExecutionUtil {
 
   @Nullable
   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();
-    }
+    return ClassUtil.getJVMClassName(aClass);
   }
 
   @Nullable
@@ -140,6 +134,7 @@ public class JavaExecutionUtil {
 
   @Nullable
   public static PsiClass findMainClass(final Project project, final String mainClassName, final GlobalSearchScope scope) {
+    if (project.isDefault()) return null;
     final PsiManager psiManager = PsiManager.getInstance(project);
     final String shortName = StringUtil.getShortName(mainClassName);
     final String packageName = StringUtil.getPackageName(mainClassName);
index 91f0f6be7c791e2cd4d8f39659a5fd43cfe46466..46812a81f0051a4eeec035d6c1a5fa702394e74d 100644 (file)
 package com.intellij.psi.impl.file;
 
 import com.intellij.ide.projectView.ProjectView;
-import com.intellij.ide.projectView.impl.PackageViewPane;
-import com.intellij.ide.projectView.impl.ProjectRootsUtil;
-import com.intellij.ide.projectView.impl.nodes.PackageElement;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.command.undo.GlobalUndoableAction;
 import com.intellij.openapi.command.undo.UndoManager;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.fileEditor.FileEditorManager;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.module.ModuleUtil;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.roots.*;
 import com.intellij.openapi.vfs.VfsUtil;
@@ -31,9 +32,7 @@ import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.openapi.wm.ToolWindow;
 import com.intellij.openapi.wm.ToolWindowId;
 import com.intellij.openapi.wm.ToolWindowManager;
-import com.intellij.psi.NonClasspathClassFinder;
-import com.intellij.psi.PsiDirectory;
-import com.intellij.psi.PsiPackage;
+import com.intellij.psi.*;
 import com.intellij.psi.impl.PackagePrefixElementFinder;
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.psi.util.PsiModificationTracker;
@@ -137,18 +136,36 @@ public class PsiPackageImplementationHelperImpl extends PsiPackageImplementation
       @Override
       public void run() {
         final ProjectView projectView = ProjectView.getInstance(project);
-        projectView.changeView(PackageViewPane.ID);
-        final PsiDirectory[] directories = psiPackage.getDirectories();
-        final VirtualFile firstDir = directories[0].getVirtualFile();
-        final boolean isLibraryRoot = ProjectRootsUtil.isLibraryRoot(firstDir, project);
-
-        final Module module = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(firstDir);
-        final PackageElement packageElement = new PackageElement(module, psiPackage, isLibraryRoot);
-        projectView.getProjectViewPaneById(PackageViewPane.ID).select(packageElement, firstDir, requestFocus);
+        PsiDirectory[] directories = suggestMostAppropriateDirectories(psiPackage);
+        if (directories.length == 0) return;
+        projectView.select(directories[0], directories[0].getVirtualFile(), requestFocus);
       }
     });
   }
 
+  private static PsiDirectory[] suggestMostAppropriateDirectories(PsiPackage psiPackage) {
+    final Project project = psiPackage.getProject();
+    PsiDirectory[] directories = null;
+    final Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
+    if (editor != null) {
+      final Document document = editor.getDocument();
+      final PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document);
+      if (psiFile != null) {
+        final Module module = ModuleUtil.findModuleForPsiElement(psiFile);
+        if (module != null) {
+          directories = psiPackage.getDirectories(GlobalSearchScope.moduleWithDependenciesScope(module));
+        } else {
+          directories = psiPackage.getDirectories(GlobalSearchScope.notScope(GlobalSearchScope.projectScope(project)));
+        }
+      }
+    }
+
+    if (directories == null || directories.length == 0) {
+      directories = psiPackage.getDirectories();
+    }
+    return directories;
+  }
+
   @Override
   public boolean packagePrefixExists(PsiPackage psiPackage) {
     return PackagePrefixElementFinder.getInstance(psiPackage.getProject()).packagePrefixExists(psiPackage.getQualifiedName());
index 818fb9b5d33720476c3031a44b10c0899d56b55f..dfa8c7417307f7ed495810c2eb6a89772aa93edf 100644 (file)
@@ -47,7 +47,10 @@ import com.intellij.psi.codeStyle.*;
 import com.intellij.psi.impl.PsiDiamondTypeUtil;
 import com.intellij.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy;
 import com.intellij.psi.impl.source.tree.java.ReplaceExpressionUtil;
-import com.intellij.psi.util.*;
+import com.intellij.psi.util.PsiExpressionTrimRenderer;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.PsiUtilBase;
 import com.intellij.refactoring.*;
 import com.intellij.refactoring.introduce.inplace.AbstractInplaceIntroducer;
 import com.intellij.refactoring.introduce.inplace.OccurrencesChooser;
@@ -100,8 +103,7 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
       final PsiElement[] statementsInRange = findStatementsAtOffset(editor, file, offset);
 
       //try line selection
-      if (statementsInRange.length == 1 && (PsiUtilCore.hasErrorElementChild(statementsInRange[0]) ||
-                                            !PsiUtil.isStatement(statementsInRange[0]) ||
+      if (statementsInRange.length == 1 && (!PsiUtil.isStatement(statementsInRange[0]) ||
                                             statementsInRange[0].getTextRange().getStartOffset() > offset ||
                                             statementsInRange[0].getTextRange().getEndOffset() < offset ||
                                             isPreferStatements())) {
index b0ee1e42eb8766cd67ad72a613eb6a3a0ddb7b02..96720321c9fee6e1eaa09f29a427a95d01df1f0c 100644 (file)
@@ -71,6 +71,7 @@
               <grid row="0" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
             </constraints>
             <properties>
+              <margin top="2" left="0" bottom="2" right="3"/>
               <text resource-bundle="messages/IdeBundle" key="unscramble.use.unscrambler.checkbox"/>
             </properties>
           </component>
           <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
         </constraints>
         <properties>
+          <margin top="2" left="0" bottom="2" right="3"/>
           <text value="Automatically detect and analyze thread dumps copied to the clipboard outside of IntelliJ IDEA"/>
         </properties>
       </component>
       <grid id="28646" binding="myBottomPanel" custom-create="true" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-        <margin top="0" left="0" bottom="0" right="0"/>
+        <margin top="0" left="3" bottom="0" right="0"/>
         <constraints>
           <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
         </constraints>
index 22e98032eb8a2523f23f5579266a0bea63d2cd54..c9f49dbf0d199ffaec57265cc699b21bdea62d60 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2012 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 package com.intellij.codeInsight;
 
 import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Computable;
 import com.intellij.openapi.util.NullableComputable;
 import com.intellij.psi.*;
 import com.intellij.psi.controlFlow.*;
 import com.intellij.psi.impl.PsiImplUtil;
 import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.util.InheritanceUtil;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.psi.search.ProjectScope;
+import com.intellij.psi.util.*;
 import com.intellij.util.NullableFunction;
 import com.intellij.util.containers.ContainerUtil;
 import gnu.trove.THashSet;
@@ -347,18 +347,26 @@ public class ExceptionUtil {
 
   @NotNull
   public static List<PsiClassType> getUnhandledCloserExceptions(final PsiResourceVariable resource, @Nullable final PsiElement topElement) {
-    final PsiType resourceType = resource.getType();
-    if (resourceType instanceof PsiClassType) {
-      final PsiClass resourceClass = ((PsiClassType)resourceType).resolve();
-      if (resourceClass != null) {
-        final PsiMethod[] closers = resourceClass.findMethodsByName("close", false);
-        for (final PsiMethod method : closers) {
-          if (method.getParameterList().getParametersCount() == 0) {
-            return getUnhandledExceptions(method, resource, topElement, PsiSubstitutor.EMPTY);
+    final Project project = resource.getProject();
+    final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
+    final PsiClass autoCloseable = facade.findClass(CommonClassNames.JAVA_LANG_AUTO_CLOSEABLE, ProjectScope.getLibrariesScope(project));
+    if (autoCloseable != null) {
+      final PsiMethod[] methods = autoCloseable.findMethodsByName("close", false);
+      if (methods.length == 1) {
+        final MethodSignature signature = methods[0].getSignature(PsiSubstitutor.EMPTY);
+        final PsiType resourceType = resource.getType();
+        if (resourceType instanceof PsiClassType) {
+          final PsiClass resourceClass = ((PsiClassType)resourceType).resolve();
+          if (resourceClass != null) {
+            final PsiMethod method = MethodSignatureUtil.findMethodBySignature(resourceClass, signature, true);
+            if (method != null) {
+              return getUnhandledExceptions(method, resource, topElement, PsiSubstitutor.EMPTY);
+            }
           }
         }
       }
     }
+
     return Collections.emptyList();
   }
 
index ccb8e83f70e2745af9af82fb9ccd952dde707bba..510cab79e4deb9d17d7e7b7b1b66353b6c827723 100644 (file)
@@ -27,6 +27,7 @@ import com.intellij.psi.tree.TokenSet;
 import com.intellij.util.text.CharArrayUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.PropertyKey;
 
 import static com.intellij.lang.PsiBuilderUtil.expect;
 import static com.intellij.lang.PsiBuilderUtil.nextTokenType;
@@ -86,7 +87,7 @@ public class DeclarationParser {
     }
     parseClassBodyDeclarations(builderWrapper, isAnnotation);
 
-    expectOrError(builder, JavaTokenType.RBRACE, JavaErrorMessages.message("expected.rbrace"));
+    expectOrError(builder, JavaTokenType.RBRACE, "expected.rbrace");
   }
 
   @Nullable
@@ -139,7 +140,7 @@ public class DeclarationParser {
       }
 
       if (declarationsAfterEnd) {
-        expectOrError(builder, JavaTokenType.RBRACE, JavaErrorMessages.message("expected.rbrace"));
+        expectOrError(builder, JavaTokenType.RBRACE, "expected.rbrace");
       }
     }
 
@@ -426,7 +427,7 @@ public class DeclarationParser {
                                                               final boolean anno, final boolean constructor) {
     parseParameterList(builder);
 
-    eatBrackets(builder, constructor, JavaErrorMessages.message("expected.semicolon"));
+    eatBrackets(builder, constructor, "expected.semicolon");
 
     if (areTypeAnnotationsSupported(builder)) {
       final PsiBuilder.Marker receiver = builder.mark();
@@ -489,8 +490,8 @@ public class DeclarationParser {
     builder.advanceLexer();
 
     final IElementType delimiter = resources ? JavaTokenType.SEMICOLON : JavaTokenType.COMMA;
-    final String noDelimiterMsg = JavaErrorMessages.message(resources ? "expected.semicolon" : "expected.comma");
-    final String noElementMsg = JavaErrorMessages.message(resources ? "expected.resource" : "expected.parameter");
+    final String noDelimiterMsg = resources ? "expected.semicolon" : "expected.comma";
+    final String noElementMsg = resources ? "expected.resource" : "expected.parameter";
 
     PsiBuilder.Marker invalidElements = null;
     String errorMessage = null;
@@ -548,7 +549,7 @@ public class DeclarationParser {
 
       if (invalidElements == null) {
         if (builder.getTokenType() == delimiter) {
-          error(builder, noElementMsg);
+          error(builder, JavaErrorMessages.message(noElementMsg));
           builder.advanceLexer();
           if (noElements && resources) {
             noElements = false;
@@ -557,7 +558,7 @@ public class DeclarationParser {
         }
         else {
           invalidElements = builder.mark();
-          errorMessage = delimiterExpected ? noDelimiterMsg : noElementMsg;
+          errorMessage = JavaErrorMessages.message(delimiterExpected ? noDelimiterMsg : noElementMsg);
         }
       }
 
@@ -613,7 +614,7 @@ public class DeclarationParser {
 
     if (expect(builder, JavaTokenType.IDENTIFIER)) {
       if (!resource) {
-        eatBrackets(builder, typeInfo != null && typeInfo.isVarArg, JavaErrorMessages.message("expected.rparen"));
+        eatBrackets(builder, typeInfo != null && typeInfo.isVarArg, "expected.rparen");
         done(param, JavaElementType.PARAMETER);
         return param;
       }
@@ -624,7 +625,7 @@ public class DeclarationParser {
       return modListInfo.first;
     }
 
-    if (expectOrError(builder, JavaTokenType.EQ, JavaErrorMessages.message("expected.eq"))) {
+    if (expectOrError(builder, JavaTokenType.EQ, "expected.eq")) {
       if (myExpressionParser.parse(builder) == null) {
         error(builder, JavaErrorMessages.message("expected.expression"));
       }
@@ -720,7 +721,8 @@ public class DeclarationParser {
     return declaration;
   }
 
-  private static boolean eatBrackets(final PsiBuilder builder, final boolean isError, @Nullable final String error) {
+  private static boolean eatBrackets(final PsiBuilder builder, final boolean isError,
+                                     @Nullable @PropertyKey(resourceBundle = JavaErrorMessages.BUNDLE) String errorKey) {
     if (builder.getTokenType() != JavaTokenType.LBRACKET) return true;
 
     final PsiBuilder.Marker marker = isError ? builder.mark() : null;
@@ -735,7 +737,7 @@ public class DeclarationParser {
     }
 
     if (marker != null) {
-      marker.error(error);
+      marker.error(errorKey != null ? JavaErrorMessages.message(errorKey):null);
     }
 
     return result;
@@ -840,9 +842,9 @@ public class DeclarationParser {
       pair = builder.mark();
     }
 
-    final boolean hasName = expectOrError(builder, JavaTokenType.IDENTIFIER, JavaErrorMessages.message("expected.identifier"));
+    final boolean hasName = expectOrError(builder, JavaTokenType.IDENTIFIER, "expected.identifier");
 
-    expectOrError(builder, JavaTokenType.EQ, JavaErrorMessages.message("expected.eq"));
+    expectOrError(builder, JavaTokenType.EQ, "expected.eq");
 
     parseAnnotationValue(builder);
 
index 8424d8defa817d3b693cbcae9546452a62347a98..2699fad161cac4b6c53cf12db30c74b5d514d1d3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2012 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -404,7 +404,7 @@ public class ExpressionParser {
           final PsiBuilder.Marker refExpr = expr.precede();
           myReferenceParser.parseReferenceParameterList(builder, false, false);
 
-          if (!JavaParserUtil.expectOrError(builder, JavaTokenType.IDENTIFIER, JavaErrorMessages.message("expected.identifier"))) {
+          if (!JavaParserUtil.expectOrError(builder, JavaTokenType.IDENTIFIER, "expected.identifier")) {
             refExpr.done(JavaElementType.REFERENCE_EXPRESSION);
             startMarker.drop();
             return refExpr;
@@ -726,7 +726,7 @@ public class ExpressionParser {
         }
         bracketCount++;
 
-        if (!JavaParserUtil.expectOrError(builder, JavaTokenType.RBRACKET, JavaErrorMessages.message("expected.rbracket"))) {
+        if (!JavaParserUtil.expectOrError(builder, JavaTokenType.RBRACKET, "expected.rbracket")) {
           newExpr.done(JavaElementType.NEW_EXPRESSION);
           return newExpr;
         }
@@ -812,7 +812,7 @@ public class ExpressionParser {
       }
     }
 
-    final boolean closed = JavaParserUtil.expectOrError(builder, JavaTokenType.RPARENTH, JavaErrorMessages.message("expected.rparen"));
+    final boolean closed = JavaParserUtil.expectOrError(builder, JavaTokenType.RPARENTH, "expected.rparen");
 
     list.done(JavaElementType.EXPRESSION_LIST);
     if (!closed) {
@@ -827,35 +827,29 @@ public class ExpressionParser {
 
   @Nullable
   private static IElementType getGtTokenType(final PsiBuilder builder) {
-    final PsiBuilder.Marker sp = builder.mark();
-
     IElementType tokenType = builder.getTokenType();
-    if (tokenType == JavaTokenType.GT) {
-      builder.advanceLexer();
-      if (builder.getTokenType() == JavaTokenType.GT) {
-        builder.advanceLexer();
-        if (builder.getTokenType() == JavaTokenType.GT) {
-          builder.advanceLexer();
-          if (builder.getTokenType() == JavaTokenType.EQ) {
-            tokenType = JavaTokenType.GTGTGTEQ;
-          }
-          else {
-            tokenType = JavaTokenType.GTGTGT;
-          }
-        }
-        else if (builder.getTokenType() == JavaTokenType.EQ) {
-          tokenType = JavaTokenType.GTGTEQ;
+    if (tokenType != JavaTokenType.GT) return tokenType;
+
+    if (builder.rawLookup(1) == JavaTokenType.GT) {
+      if (builder.rawLookup(2) == JavaTokenType.GT) {
+        if (builder.rawLookup(3) == JavaTokenType.EQ) {
+          tokenType = JavaTokenType.GTGTGTEQ;
         }
         else {
-          tokenType = JavaTokenType.GTGT;
+          tokenType = JavaTokenType.GTGTGT;
         }
       }
-      else if (builder.getTokenType() == JavaTokenType.EQ) {
-        tokenType = JavaTokenType.GE;
+      else if (builder.rawLookup(2) == JavaTokenType.EQ) {
+        tokenType = JavaTokenType.GTGTEQ;
       }
+      else {
+        tokenType = JavaTokenType.GTGT;
+      }
+    }
+    else if (builder.rawLookup(1) == JavaTokenType.EQ) {
+      tokenType = JavaTokenType.GE;
     }
 
-    sp.rollbackTo();
     return tokenType;
   }
 
index d3fd09cc889fe502f2346914d4a0679b4563e398..6af4ce564138ca7511ac4037a61d20916c63a234 100644 (file)
@@ -39,6 +39,7 @@ import com.intellij.psi.tree.TokenSet;
 import com.intellij.psi.util.PsiUtil;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.PropertyKey;
 
 import java.util.List;
 
@@ -258,9 +259,10 @@ public class JavaParserUtil {
     }
   }
 
-  public static boolean expectOrError(final PsiBuilder builder, final IElementType expectedType, final String errorMessage) {
+  public static boolean expectOrError(final PsiBuilder builder, final IElementType expectedType,
+                                      @PropertyKey(resourceBundle = JavaErrorMessages.BUNDLE) String errorMessageKey) {
     if (!PsiBuilderUtil.expect(builder, expectedType)) {
-      error(builder, errorMessage);
+      error(builder, JavaErrorMessages.message(errorMessageKey));
       return false;
     }
     return true;
@@ -275,7 +277,7 @@ public class JavaParserUtil {
   }
 
   public static void semicolon(final PsiBuilder builder) {
-    expectOrError(builder, JavaTokenType.SEMICOLON, JavaErrorMessages.message("expected.semicolon"));
+    expectOrError(builder, JavaTokenType.SEMICOLON, "expected.semicolon");
   }
 
   public static PsiBuilder braceMatchingBuilder(final PsiBuilder builder) {
index 68fd2ff197e3d40fbf16b55f2cd6c09ce04b0384..9382af0cac6bf4b58a05924ea4d73f7bb000c1d4 100644 (file)
@@ -293,7 +293,7 @@ public class ReferenceParser {
       if (expect(builder, JavaTokenType.GT)) {
         break;
       }
-      else if (!expectOrError(builder, JavaTokenType.COMMA, JavaErrorMessages.message("expected.gt.or.comma"))) {
+      else if (!expectOrError(builder, JavaTokenType.COMMA, "expected.gt.or.comma")) {
         isOk = false;
         break;
       }
index b4294f6a4cd94c15d9312690d33ce5264fc47af0..95ad7cfd72a86f3e71b9714807fbe5ee62feb7c9 100644 (file)
@@ -131,7 +131,7 @@ public class StatementParser {
 
     parseStatements(builder, parseUntilEof ? BraceMode.TILL_LAST : BraceMode.TILL_FIRST);
 
-    final boolean greedyBlock = !expectOrError(builder, JavaTokenType.RBRACE, JavaErrorMessages.message("expected.rbrace"));
+    final boolean greedyBlock = !expectOrError(builder, JavaTokenType.RBRACE, "expected.rbrace");
     builder.getTokenType(); // eat spaces
 
     done(codeBlock, JavaElementType.CODE_BLOCK);
@@ -543,7 +543,7 @@ public class StatementParser {
       }
     }
 
-    expectOrError(builder, JavaTokenType.COLON, JavaErrorMessages.message("expected.colon"));
+    expectOrError(builder, JavaTokenType.COLON, "expected.colon");
 
     done(statement, JavaElementType.SWITCH_LABEL_STATEMENT);
     return statement;
index 317aeb1326bbbaaf0b2f92e8fb435a80c0c5498a..1c83fe4b348062a81f842ca658a5e728bbce4843 100644 (file)
@@ -328,6 +328,7 @@ expected.lparen.or.lbracket='(' or '[' expected
 expected.array.initializer=Array initializer expected
 unexpected.tokens=Unexpected tokens
 expected.gt.or.comma='>' or ',' expected.
+string.expected=String literal expected
 else.without.if='else' without 'if'
 catch.without.try='catch' without 'try'
 finally.without.try='finally' without 'try'
index e8df782c83ac473628e9f610cf635b93a430f0e9..c0f8eb7cc342cea8471b5f0973f1a2017113d85e 100644 (file)
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 class C {
   static class E extends Exception { }
   static class E1 extends E { }
@@ -10,6 +25,8 @@ class C {
     @Override public void close() throws E3 { }
   }
 
+  static interface I extends AutoCloseable { }
+
   void m1() {
     try (MyResource r = new MyResource()) { r.doSomething(); }
     catch (E1 | E2 | E3 ignore) { }
@@ -24,6 +41,8 @@ class C {
     catch (E3 e) { }
 
     try (MyResource r = <error descr="Unhandled exception: C.E1">new MyResource()</error>) { }
+
+    try (<error descr="Unhandled exception from auto-closeable resource: java.lang.Exception">I r = null</error>) { System.out.println(r); }
   }
 
   void m2() throws Exception {
diff --git a/java/java-tests/testData/psi/parser-partial/expressions/Binary2.txt b/java/java-tests/testData/psi/parser-partial/expressions/Binary2.txt
new file mode 100644 (file)
index 0000000..f9e6038
--- /dev/null
@@ -0,0 +1,18 @@
+PsiJavaFile:Binary2.java
+  PsiAssignmentExpression:a > = b
+    PsiBinaryExpression:a >
+      PsiReferenceExpression:a
+        PsiReferenceParameterList
+          <empty list>
+        PsiIdentifier:a('a')
+      PsiWhiteSpace(' ')
+      PsiJavaToken:GT('>')
+      PsiErrorElement:Expression expected
+        <empty list>
+    PsiWhiteSpace(' ')
+    PsiJavaToken:EQ('=')
+    PsiWhiteSpace(' ')
+    PsiReferenceExpression:b
+      PsiReferenceParameterList
+        <empty list>
+      PsiIdentifier:b('b')
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/parser-partial/expressions/Binary3.txt b/java/java-tests/testData/psi/parser-partial/expressions/Binary3.txt
new file mode 100644 (file)
index 0000000..5e5a071
--- /dev/null
@@ -0,0 +1,18 @@
+PsiJavaFile:Binary3.java
+  PsiAssignmentExpression:a >/**/= b
+    PsiBinaryExpression:a >
+      PsiReferenceExpression:a
+        PsiReferenceParameterList
+          <empty list>
+        PsiIdentifier:a('a')
+      PsiWhiteSpace(' ')
+      PsiJavaToken:GT('>')
+      PsiErrorElement:Expression expected
+        <empty list>
+    PsiComment(C_STYLE_COMMENT)('/**/')
+    PsiJavaToken:EQ('=')
+    PsiWhiteSpace(' ')
+    PsiReferenceExpression:b
+      PsiReferenceParameterList
+        <empty list>
+      PsiIdentifier:b('b')
\ No newline at end of file
index 85e3069f767d07a8ab3453d7a7f9aebcf70a5fa8..b4e835b2a079d07d1f331871500bc6e25fde4478 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2012 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -54,7 +54,7 @@ public class JavaLexerTest extends LexerTestCase {
            "DOUBLE_LITERAL ('1e137')");
   }
 
-  public void testTigerNumericLiterals() throws Exception {
+  public void testTigerNumericLiterals() {
     doTest("0xap0f 0xab.p0F 0x.abcP0f 0xabc.defP0F",
            "FLOAT_LITERAL ('0xap0f')\nWHITE_SPACE (' ')\n" +
            "FLOAT_LITERAL ('0xab.p0F')\nWHITE_SPACE (' ')\n" +
@@ -115,7 +115,7 @@ public class JavaLexerTest extends LexerTestCase {
            "DOUBLE_LITERAL ('0xa_bc.de_fP1_234D')");
   }
 
-  public void testMalformedCoinLiterals() throws Exception {
+  public void testMalformedCoinLiterals() {
     doTest("0_ _1 0_8 0x_f 0b_1 0B2 0x1.0_p-1 1.0e_1022",
            "INTEGER_LITERAL ('0')\nIDENTIFIER ('_')\nWHITE_SPACE (' ')\n" +
            "IDENTIFIER ('_1')\nWHITE_SPACE (' ')\n" +
@@ -127,6 +127,13 @@ public class JavaLexerTest extends LexerTestCase {
            "DOUBLE_LITERAL ('1.0e')\nIDENTIFIER ('_1022')");
   }
 
+  public void testMalformedOperators() {
+    doTest("(i > = 0)",
+           "LPARENTH ('(')\nIDENTIFIER ('i')\nWHITE_SPACE (' ')\n" +
+           "GT ('>')\nWHITE_SPACE (' ')\nEQ ('=')\n" +
+           "WHITE_SPACE (' ')\nINTEGER_LITERAL ('0')\nRPARENTH (')')\n");
+  }
+
   @Override
   protected Lexer createLexer() {
     return new JavaLexer(LanguageLevel.HIGHEST);
index fdc02ee9bf875b42db2d946cf55d0c2064c3d230..471190ed31794fa40ae7132c07bce38cb3b1d892 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * Copyright 2000-2012 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -32,6 +32,8 @@ public class ExpressionParserTest extends JavaParsingTestCase {
 
   public void testBinary0() { doParserTest("a + b"); }
   public void testBinary1() { doParserTest("a < b"); }
+  public void testBinary2() { doParserTest("a > = b"); }
+  public void testBinary3() { doParserTest("a >/**/= b"); }
 
   public void testCond0() { doParserTest("cond ? true : false"); }
   public void testCond1() { doParserTest("cond ?"); }
index 18038c40c13d847c415fdc1d941768947ad9c4a3..d7f8aa2a27c2b02c26cf803943d2f4163c897cbd 100644 (file)
@@ -245,26 +245,19 @@ public class ClassUtil {
 
   @Nullable
   public static String getJVMClassName(PsiClass aClass) {
-    final String qName = aClass.getQualifiedName();
-    if (qName == null) return null;
-    return replaceDotsWithDollars(qName, aClass);
-  }
-
-  private static String replaceDotsWithDollars(final String qName, PsiClass aClass) {
-    StringBuilder qNameBuffer = new StringBuilder(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();
+    final PsiClass containingClass = aClass.getContainingClass();
+    if (containingClass != null) {
+      String parentName = getJVMClassName(containingClass);
+      if (parentName == null) {
+        return null;
+      }
+      
+      return parentName + "$" + aClass.getName();
     }
-    return qNameBuffer.toString();
+    return aClass.getQualifiedName();
   }
 
+
   @Nullable
   public static PsiClass findPsiClassByJVMName(final PsiManager manager, final String jvmClassName) {
     return findPsiClass(manager, jvmClassName.replace('/', '.'), null, true);
index 4ad2f7edc851a1777c2434ff9425f776f78b4e34..517f2a226ff41cc0372885cb43d02b8e48111d78 100644 (file)
@@ -131,11 +131,13 @@ public class ClassFilterEditor extends JPanel implements ComponentWithEmptyText
       }
     });
 
+    myAddPatternButton.setEnabled(!myProject.isDefault());
     myAddPatternButton.addActionListener(new ActionListener() {
       public void actionPerformed(ActionEvent e) {
         addPatternFilter();
       }
     });
+    myAddClassButton.setEnabled(!myProject.isDefault());
     myAddClassButton.addActionListener(new ActionListener() {
       public void actionPerformed(ActionEvent e) {
         addClassFilter();
index 44ce03bbb0aba23beb80089befce061b7052977e..1dc3be12660ed8bda5c50141e32d4a0ea984cb49 100644 (file)
@@ -42,6 +42,9 @@ public class DefaultLightProjectDescriptor implements LightProjectDescriptor {
 
   @Override
   public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) {
-    model.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(LanguageLevel.HIGHEST);
+    LanguageLevelModuleExtension extension = model.getModuleExtension(LanguageLevelModuleExtension.class);
+    if (extension != null) {
+      extension.setLanguageLevel(LanguageLevel.HIGHEST);
+    }
   }
 }
diff --git a/jps/jps-builders/src/defaultLogConfig.xml b/jps/jps-builders/src/defaultLogConfig.xml
new file mode 100644 (file)
index 0000000..c57f244
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+  <appender name="console" class="org.apache.log4j.ConsoleAppender">
+    <param name="Target" value="System.err"/>
+    <layout class="org.apache.log4j.PatternLayout">
+      <param name="ConversionPattern" value="%-5p %c{1} - %m%n"/>
+    </layout>
+  </appender>
+
+  <root>
+    <priority value ="info" />
+    <appender-ref ref="console" />
+  </root>
+
+</log4j:configuration>
index 2c642f0df771aae70fa6ac69c5d306c4aab6cb6d..4bfc4b9c294e5a7e472bbbdb00ba02b9c4596dcb 100644 (file)
 package org.jetbrains.jps.incremental;
 
-import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.io.FileUtil;
-import org.jetbrains.ether.dependencyView.Mappings;
-import org.jetbrains.jps.Module;
-import org.jetbrains.jps.ModuleChunk;
-import org.jetbrains.jps.incremental.storage.SourceToOutputMapping;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.*;
-
 /**
- * @author Eugene Zhuravlev
- *         Date: 9/17/11
+ * @author nik
  */
 public abstract class Builder {
-  private static final Key<Set<File>> ALL_AFFECTED_FILES_KEY = Key.create("_all_affected_files_");
-  private static final Key<Set<File>> ALL_COMPILED_FILES_KEY = Key.create("_all_compiled_files_");
-
-  public static enum ExitCode {
-    OK, ABORT, ADDITIONAL_PASS_REQUIRED
-  }
-
   public abstract String getName();
 
-  public abstract ExitCode build(CompileContext context, ModuleChunk chunk) throws ProjectBuildException;
-
   public abstract String getDescription();
-
-  public void cleanupResources(CompileContext context, ModuleChunk chunk) {
-    ALL_AFFECTED_FILES_KEY.set(context, null);
-    ALL_COMPILED_FILES_KEY.set(context, null);
-  }
-
-  /**
-   * @param context
-   * @param delta
-   * @param chunk
-   * @param filesToCompile files compiled in this round
-   * @param successfullyCompiled
-   * @return true if additional compilation pass is required, false otherwise
-   * @throws Exception
-   */
-  public final boolean updateMappings(CompileContext context, final Mappings delta, ModuleChunk chunk, Collection<File> filesToCompile, Collection<File> successfullyCompiled) throws Exception {
-    try {
-      boolean additionalPassRequired = false;
-
-      final Set<String> removedPaths = getRemovedPaths(context);
-
-      final Mappings globalMappings = context.getDataManager().getMappings();
-
-      //noinspection SynchronizationOnLocalVariableOrMethodParameter
-      synchronized (globalMappings) {
-        if (!context.isProjectRebuild() && context.shouldDifferentiate(chunk, context.isCompilingTests())) {
-          final Set<File> allCompiledFiles = getAllCompiledFilesContainer(context);
-          final Set<File> allAffectedFiles = getAllAffectedFilesContainer(context);
-
-          // mark as affected all files that were dirty before compilation
-          allAffectedFiles.addAll(filesToCompile);
-          // accumulate all successfully compiled in this round
-          allCompiledFiles.addAll(successfullyCompiled);
-          // unmark as affected all successfully compiled
-          allAffectedFiles.removeAll(successfullyCompiled);
-
-          final HashSet<File> affectedBeforeDif = new HashSet<File>(allAffectedFiles);
-
-          final boolean incremental = globalMappings.differentiate(
-            delta, removedPaths, successfullyCompiled, allCompiledFiles, allAffectedFiles
-          );
-
-          if (incremental) {
-            final Set<File> newlyAffectedFiles = new HashSet<File>(allAffectedFiles);
-            newlyAffectedFiles.removeAll(affectedBeforeDif);
-            newlyAffectedFiles.removeAll(allCompiledFiles); // the diff operation may have affected the class already compiled in thic compilation round
-
-            if (!newlyAffectedFiles.isEmpty()) {
-              for (File file : newlyAffectedFiles) {
-                context.markDirty(file);
-              }
-              additionalPassRequired = context.isMake() && chunkContainsAffectedFiles(context, chunk, newlyAffectedFiles);
-            }
-          }
-          else {
-            additionalPassRequired = context.isMake();
-            context.markDirtyRecursively(chunk);
-          }
-        }
-
-        globalMappings.integrate(delta, successfullyCompiled, removedPaths);
-      }
-
-      return additionalPassRequired;
-    }
-    catch(RuntimeException e) {
-      final Throwable cause = e.getCause();
-      if (cause instanceof IOException) {
-        throw ((IOException)cause);
-      }
-      throw e;
-    }
-  }
-
-  // delete all class files that according to mappings correspond to given sources
-  public static void deleteCorrespondingOutputFiles(CompileContext context, Map<File, Module> sources) throws Exception {
-    if (!context.isProjectRebuild() && !sources.isEmpty()) {
-      for (Map.Entry<File, Module> pair : sources.entrySet()) {
-        final File file = pair.getKey();
-        final String srcPath = FileUtil.toSystemIndependentName(file.getPath());
-        final String moduleName = pair.getValue().getName().toLowerCase(Locale.US);
-        final SourceToOutputMapping srcToOut = context.getDataManager().getSourceToOutputMap(moduleName, context.isCompilingTests());
-        final Collection<String> outputs = srcToOut.getState(srcPath);
-        if (outputs != null) {
-          for (String output : outputs) {
-            FileUtil.delete(new File(output));
-          }
-          srcToOut.remove(srcPath);
-        }
-      }
-    }
-  }
-
-  private static boolean chunkContainsAffectedFiles(CompileContext context, ModuleChunk chunk, final Set<File> affected) throws Exception {
-    final Set<Module> chunkModules = new HashSet<Module>(chunk.getModules());
-    if (!chunkModules.isEmpty()) {
-      for (File file : affected) {
-        final RootDescriptor moduleAndRoot = context.getModuleAndRoot(file);
-        if (moduleAndRoot != null && chunkModules.contains(moduleAndRoot.module)) {
-          return true;
-        }
-      }
-    }
-    return false;
-  }
-
-  private static Set<File> getAllAffectedFilesContainer(CompileContext context) {
-    Set<File> allAffectedFiles = ALL_AFFECTED_FILES_KEY.get(context);
-    if (allAffectedFiles == null) {
-      allAffectedFiles = new HashSet<File>();
-      ALL_AFFECTED_FILES_KEY.set(context, allAffectedFiles);
-    }
-    return allAffectedFiles;
-  }
-
-  private static Set<File> getAllCompiledFilesContainer(CompileContext context) {
-    Set<File> allCompiledFiles = ALL_COMPILED_FILES_KEY.get(context);
-    if (allCompiledFiles == null) {
-      allCompiledFiles = new HashSet<File>();
-      ALL_COMPILED_FILES_KEY.set(context, allCompiledFiles);
-    }
-    return allCompiledFiles;
-  }
-
-  private static Set<String> getRemovedPaths(CompileContext context) {
-    final Set<String> removed = Paths.CHUNK_REMOVED_SOURCES_KEY.get(context);
-    return removed != null? removed : Collections.<String>emptySet();
-  }
-
 }
index 7840245b8409a31cee09c968cee4b12c2cf5ebca..51a128ddc6ff0670bcb8a7e7d0c113dcba979932 100644 (file)
@@ -2,7 +2,7 @@ package org.jetbrains.jps.incremental;
 
 import org.jetbrains.jps.incremental.groovy.GroovyBuilder;
 import org.jetbrains.jps.incremental.java.JavaBuilder;
-import org.jetbrains.jps.incremental.resourses.ResourcesBuilder;
+import org.jetbrains.jps.incremental.resources.ResourcesBuilder;
 
 import java.util.*;
 import java.util.concurrent.ExecutorService;
@@ -16,7 +16,7 @@ public class BuilderRegistry {
   private static class Holder {
     static final BuilderRegistry ourInstance = new BuilderRegistry();
   }
-  private final Map<BuilderCategory, List<Builder>> myBuilders = new HashMap<BuilderCategory, List<Builder>>();
+  private final Map<BuilderCategory, List<ModuleLevelBuilder>> myBuilders = new HashMap<BuilderCategory, List<ModuleLevelBuilder>>();
   private ExecutorService myTasksExecutor;
 
   public static BuilderRegistry getInstance() {
@@ -25,7 +25,7 @@ public class BuilderRegistry {
 
   private BuilderRegistry() {
     for (BuilderCategory category : BuilderCategory.values()) {
-      myBuilders.put(category, new ArrayList<Builder>());
+      myBuilders.put(category, new ArrayList<ModuleLevelBuilder>());
     }
     final Runtime runtime = Runtime.getRuntime();
     myTasksExecutor = Executors.newFixedThreadPool(runtime.availableProcessors());
@@ -60,7 +60,7 @@ public class BuilderRegistry {
     return Collections.emptyList(); // todo
   }
 
-  public List<Builder> getBuilders(BuilderCategory category){
+  public List<ModuleLevelBuilder> getBuilders(BuilderCategory category){
     return Collections.unmodifiableList(myBuilders.get(category)); // todo
   }
 
index 65efacbb9bcbcb9731b8dce674bf1a190a5b7f98..ccfa9e42dc4bb611031d2873c5d13eaee82003d1 100644 (file)
@@ -314,7 +314,7 @@ public class IncProjectBuilder {
     finally {
       try {
         for (BuilderCategory category : BuilderCategory.values()) {
-          for (Builder builder : myBuilderRegistry.getBuilders(category)) {
+          for (ModuleLevelBuilder builder : myBuilderRegistry.getBuilders(category)) {
             builder.cleanupResources(context, chunk);
           }
         }
@@ -334,7 +334,7 @@ public class IncProjectBuilder {
   }
 
   private void runBuilders(CompileContext context, ModuleChunk chunk, BuilderCategory category) throws ProjectBuildException {
-    final List<Builder> builders = myBuilderRegistry.getBuilders(category);
+    final List<ModuleLevelBuilder> builders = myBuilderRegistry.getBuilders(category);
     if (builders.isEmpty()) {
       return;
     }
@@ -347,16 +347,16 @@ public class IncProjectBuilder {
     do {
       nextPassRequired = false;
       context.beforeNextCompileRound(chunk);
-      for (Builder builder : builders) {
-        final Builder.ExitCode buildResult = builder.build(context, chunk);
+      for (ModuleLevelBuilder builder : builders) {
+        final ModuleLevelBuilder.ExitCode buildResult = builder.build(context, chunk);
 
-        if (buildResult == Builder.ExitCode.ABORT) {
+        if (buildResult == ModuleLevelBuilder.ExitCode.ABORT) {
           throw new ProjectBuildException("Builder " + builder.getDescription() + " requested build stop");
         }
         if (myCancelStatus.isCanceled()) {
           throw new ProjectBuildException(CANCELED_MESSAGE);
         }
-        if (buildResult == Builder.ExitCode.ADDITIONAL_PASS_REQUIRED) {
+        if (buildResult == ModuleLevelBuilder.ExitCode.ADDITIONAL_PASS_REQUIRED) {
           if (!nextPassRequired) {
             // recalculate basis
             myModulesProcessed -= (stagesPassed * modulesInChunk) / stageCount;
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleLevelBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/ModuleLevelBuilder.java
new file mode 100644 (file)
index 0000000..314187f
--- /dev/null
@@ -0,0 +1,177 @@
+package org.jetbrains.jps.incremental;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.io.FileUtil;
+import org.jetbrains.ether.dependencyView.Mappings;
+import org.jetbrains.jps.Module;
+import org.jetbrains.jps.ModuleChunk;
+import org.jetbrains.jps.incremental.storage.SourceToOutputMapping;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: 9/17/11
+ */
+public abstract class ModuleLevelBuilder extends Builder {
+  private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.Builder");
+
+  private static final Key<Set<File>> ALL_AFFECTED_FILES_KEY = Key.create("_all_affected_files_");
+  private static final Key<Set<File>> ALL_COMPILED_FILES_KEY = Key.create("_all_compiled_files_");
+
+  public static enum ExitCode {
+    OK, ABORT, ADDITIONAL_PASS_REQUIRED
+  }
+
+  public abstract ExitCode build(CompileContext context, ModuleChunk chunk) throws ProjectBuildException;
+
+  public void cleanupResources(CompileContext context, ModuleChunk chunk) {
+    ALL_AFFECTED_FILES_KEY.set(context, null);
+    ALL_COMPILED_FILES_KEY.set(context, null);
+  }
+
+  /**
+   * @param context
+   * @param delta
+   * @param chunk
+   * @param filesToCompile files compiled in this round
+   * @param successfullyCompiled
+   * @return true if additional compilation pass is required, false otherwise
+   * @throws Exception
+   */
+  public final boolean updateMappings(CompileContext context, final Mappings delta, ModuleChunk chunk, Collection<File> filesToCompile, Collection<File> successfullyCompiled) throws Exception {
+    try {
+      boolean additionalPassRequired = false;
+
+      final Set<String> removedPaths = getRemovedPaths(context);
+
+      final Mappings globalMappings = context.getDataManager().getMappings();
+
+      //noinspection SynchronizationOnLocalVariableOrMethodParameter
+      synchronized (globalMappings) {
+        if (!context.isProjectRebuild() && context.shouldDifferentiate(chunk, context.isCompilingTests())) {
+          final Set<File> allCompiledFiles = getAllCompiledFilesContainer(context);
+          final Set<File> allAffectedFiles = getAllAffectedFilesContainer(context);
+
+          // mark as affected all files that were dirty before compilation
+          allAffectedFiles.addAll(filesToCompile);
+          // accumulate all successfully compiled in this round
+          allCompiledFiles.addAll(successfullyCompiled);
+          // unmark as affected all successfully compiled
+          allAffectedFiles.removeAll(successfullyCompiled);
+
+          final HashSet<File> affectedBeforeDif = new HashSet<File>(allAffectedFiles);
+
+          final boolean incremental = globalMappings.differentiate(
+            delta, removedPaths, successfullyCompiled, allCompiledFiles, allAffectedFiles
+          );
+
+          if (LOG.isDebugEnabled()) {
+            LOG.debug("Differentiate Results:");
+
+            LOG.debug("   Compiled Files:");
+
+            for (final File c : allCompiledFiles) {
+              LOG.debug("      " + c.getAbsolutePath());
+            }
+
+            LOG.debug("   Affected Files:");
+
+            for (final File c : allAffectedFiles) {
+              LOG.debug("      " + c.getAbsolutePath());
+            }
+
+            LOG.debug("End Of Differentiate Results.");
+          }
+
+          if (incremental) {
+            final Set<File> newlyAffectedFiles = new HashSet<File>(allAffectedFiles);
+            newlyAffectedFiles.removeAll(affectedBeforeDif);
+            newlyAffectedFiles.removeAll(allCompiledFiles); // the diff operation may have affected the class already compiled in thic compilation round
+
+            if (!newlyAffectedFiles.isEmpty()) {
+              for (File file : newlyAffectedFiles) {
+                context.markDirty(file);
+              }
+              additionalPassRequired = context.isMake() && chunkContainsAffectedFiles(context, chunk, newlyAffectedFiles);
+            }
+          }
+          else {
+            additionalPassRequired = context.isMake();
+            context.markDirtyRecursively(chunk);
+          }
+        }
+
+        globalMappings.integrate(delta, successfullyCompiled, removedPaths);
+      }
+
+      return additionalPassRequired;
+    }
+    catch(RuntimeException e) {
+      final Throwable cause = e.getCause();
+      if (cause instanceof IOException) {
+        throw ((IOException)cause);
+      }
+      throw e;
+    }
+  }
+
+  // delete all class files that according to mappings correspond to given sources
+  public static void deleteCorrespondingOutputFiles(CompileContext context, Map<File, Module> sources) throws Exception {
+    if (!context.isProjectRebuild() && !sources.isEmpty()) {
+      for (Map.Entry<File, Module> pair : sources.entrySet()) {
+        final File file = pair.getKey();
+        final String srcPath = FileUtil.toSystemIndependentName(file.getPath());
+        final String moduleName = pair.getValue().getName().toLowerCase(Locale.US);
+        final SourceToOutputMapping srcToOut = context.getDataManager().getSourceToOutputMap(moduleName, context.isCompilingTests());
+        final Collection<String> outputs = srcToOut.getState(srcPath);
+        if (outputs != null) {
+          for (String output : outputs) {
+            FileUtil.delete(new File(output));
+          }
+          srcToOut.remove(srcPath);
+        }
+      }
+    }
+  }
+
+  private static boolean chunkContainsAffectedFiles(CompileContext context, ModuleChunk chunk, final Set<File> affected) throws Exception {
+    final Set<Module> chunkModules = new HashSet<Module>(chunk.getModules());
+    if (!chunkModules.isEmpty()) {
+      for (File file : affected) {
+        final RootDescriptor moduleAndRoot = context.getModuleAndRoot(file);
+        if (moduleAndRoot != null && chunkModules.contains(moduleAndRoot.module)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  private static Set<File> getAllAffectedFilesContainer(CompileContext context) {
+    Set<File> allAffectedFiles = ALL_AFFECTED_FILES_KEY.get(context);
+    if (allAffectedFiles == null) {
+      allAffectedFiles = new HashSet<File>();
+      ALL_AFFECTED_FILES_KEY.set(context, allAffectedFiles);
+    }
+    return allAffectedFiles;
+  }
+
+  private static Set<File> getAllCompiledFilesContainer(CompileContext context) {
+    Set<File> allCompiledFiles = ALL_COMPILED_FILES_KEY.get(context);
+    if (allCompiledFiles == null) {
+      allCompiledFiles = new HashSet<File>();
+      ALL_COMPILED_FILES_KEY.set(context, allCompiledFiles);
+    }
+    return allCompiledFiles;
+  }
+
+  private static Set<String> getRemovedPaths(CompileContext context) {
+    final Set<String> removed = Paths.CHUNK_REMOVED_SOURCES_KEY.get(context);
+    return removed != null? removed : Collections.<String>emptySet();
+  }
+
+}
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/ProjectLevelBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/ProjectLevelBuilder.java
new file mode 100644 (file)
index 0000000..c829659
--- /dev/null
@@ -0,0 +1,20 @@
+package org.jetbrains.jps.incremental;
+
+/**
+ * @author nik
+ */
+public abstract class ProjectLevelBuilder extends Builder {
+  private final ProjectLevelBuilderCategory myCategory;
+
+  protected ProjectLevelBuilder(ProjectLevelBuilderCategory category) {
+    myCategory = category;
+  }
+
+  public abstract void build(CompileContext context);
+
+  public ProjectLevelBuilderCategory getCategory() {
+    return myCategory;
+  }
+
+  public static enum ProjectLevelBuilderCategory { TRANSLATOR, PACKAGER }
+}
index 2bb3e3c411abdd003692512bc40d46656272701d..7f8be2cb10a2647cd95f1cde35f1f8e8e151588a 100644 (file)
@@ -29,7 +29,7 @@ import java.util.*;
  * @author Eugene Zhuravlev
  *         Date: 10/25/11
  */
-public class GroovyBuilder extends Builder {
+public class GroovyBuilder extends ModuleLevelBuilder {
   public static final String BUILDER_NAME = "groovy";
   private final boolean myForStubs;
   private final String myBuilderName;
@@ -43,7 +43,7 @@ public class GroovyBuilder extends Builder {
     return myBuilderName;
   }
 
-  public Builder.ExitCode build(final CompileContext context, ModuleChunk chunk) throws ProjectBuildException {
+  public ModuleLevelBuilder.ExitCode build(final CompileContext context, ModuleChunk chunk) throws ProjectBuildException {
     ExitCode exitCode = ExitCode.OK;
     final Map<File, Module> toCompile = new HashMap<File, Module>();
     try {
@@ -104,12 +104,13 @@ public class GroovyBuilder extends Builder {
 
       // todo CompilerUtil.addLocaleOptions()
       //todo different outputs in a chunk
+      //todo xmx
       //todo module jdk path
       final List<String> cmd = ExternalProcessUtil.buildJavaCommandLine(
         SystemProperties.getJavaHome() + "/bin/java",
         "org.jetbrains.groovy.compiler.rt.GroovycRunner",
         Collections.<String>emptyList(), new ArrayList<String>(cp),
-        Arrays.asList("-Xmx384m"/*, "-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5858"*/),
+        Arrays.asList("-Xmx384m"/*, "-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5239"*/),
         Arrays.<String>asList(myForStubs ? "stubs" : "groovyc", tempFile.getPath())
       );
 
index 1be97a81fcf4a65d1bdd50b6ef871ab417336947..2269278c3908141d999e835d9f8d7fd6e6116e52 100644 (file)
@@ -49,7 +49,7 @@ import java.util.concurrent.ExecutorService;
  * @author Eugene Zhuravlev
  *         Date: 9/21/11
  */
-public class JavaBuilder extends Builder{
+public class JavaBuilder extends ModuleLevelBuilder {
   public static final String BUILDER_NAME = "java";
   private static final String JAVA_EXTENSION = ".java";
   private static final String FORM_EXTENSION = ".form";
similarity index 97%
rename from jps/jps-builders/src/org/jetbrains/jps/incremental/resourses/ResourcesBuilder.java
rename to jps/jps-builders/src/org/jetbrains/jps/incremental/resources/ResourcesBuilder.java
index a8b7725d3fd4b1e5fb300e5c1f7810760118f06c..a318f8ef4dd7ea1aba6de8b59dda0521d1f4693d 100644 (file)
@@ -1,4 +1,4 @@
-package org.jetbrains.jps.incremental.resourses;
+package org.jetbrains.jps.incremental.resources;
 
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.util.io.FileUtil;
@@ -19,7 +19,7 @@ import java.util.Locale;
  * @author Eugene Zhuravlev
  *         Date: 10/6/11
  */
-public class ResourcesBuilder extends Builder{
+public class ResourcesBuilder extends ModuleLevelBuilder {
   private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.incremental.resourses.ResourcesBuilder");
   public static final String BUILDER_NAME = "resources";
 
index a5c2d64754c087bfc32ad5c40073f1eccb5bd5ac..8cdde853f06cf95d68c1614217a4c09c4fd6d9b7 100644 (file)
@@ -34,6 +34,7 @@ public class Server {
   private static final int MAX_SIMULTANEOUS_BUILD_SESSIONS = Math.max(2, Runtime.getRuntime().availableProcessors());
   public static final String SERVER_SUCCESS_START_MESSAGE = "Compile Server started successfully. Listening on port: ";
   public static final String SERVER_ERROR_START_MESSAGE = "Error starting Compile Server: ";
+  private static final String LOG_FILE_NAME = "log.xml";
 
   private final ChannelGroup myAllOpenChannels = new DefaultChannelGroup("compile-server");
   private final ChannelFactory myChannelFactory;
@@ -98,70 +99,14 @@ public class Server {
       }
 
       final Server server = new Server(systemDir);
-
-      DOMConfigurator.configure("log.xml");
-
-      Logger.setFactory(new Logger.Factory() {
-        @Override
-        public Logger getLoggerInstance(String category) {
-          final org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(category);
-          
-          return new Logger(){
-            @Override
-            public boolean isDebugEnabled() {
-              return logger.isDebugEnabled();
-            }
-
-            @Override
-            public void debug(@NonNls String message) {
-              logger.debug(message);
-            }
-
-            @Override
-            public void debug(@Nullable Throwable t) {
-              logger.debug("", t);
-            }
-
-            @Override
-            public void debug(@NonNls String message, @Nullable Throwable t) {
-              logger.debug(message, t);
-            }
-
-            @Override
-            public void error(@NonNls String message, @Nullable Throwable t, @NonNls String... details) {
-              logger.debug(message, t);
-            }
-
-            @Override
-            public void info(@NonNls String message) {
-              logger.info(message);
-            }
-
-            @Override
-            public void info(@NonNls String message, @Nullable Throwable t) {
-              logger.info(message, t);
-            }
-
-            @Override
-            public void warn(@NonNls String message, @Nullable Throwable t) {
-              logger.warn(message, t);
-            }
-
-            @Override
-            public void setLevel(Level level) {
-              logger.setLevel(level);
-            }
-          };
-        }
-      });
-
-      server.start(port);
       Runtime.getRuntime().addShutdownHook(new Thread("Shutdown hook thread") {
         public void run() {
           server.stop();
         }
       });
 
+      initLoggers();
+      server.start(port);
       ServerState.getInstance().setKeepTempCachesInMemory(System.getProperty(GlobalOptions.USE_MEMORY_TEMP_CACHE_OPTION) != null);
 
       System.out.println("Server classpath: " + System.getProperty("java.class.path"));
@@ -174,6 +119,66 @@ public class Server {
     }
   }
 
+  private static void initLoggers() {
+    if (new File(LOG_FILE_NAME).exists()) {
+      DOMConfigurator.configure(LOG_FILE_NAME);
+    }
+
+    Logger.setFactory(new Logger.Factory() {
+      @Override
+      public Logger getLoggerInstance(String category) {
+        final org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(category);
+
+        return new Logger() {
+          @Override
+          public boolean isDebugEnabled() {
+            return logger.isDebugEnabled();
+          }
+
+          @Override
+          public void debug(@NonNls String message) {
+            logger.debug(message);
+          }
+
+          @Override
+          public void debug(@Nullable Throwable t) {
+            logger.debug("", t);
+          }
+
+          @Override
+          public void debug(@NonNls String message, @Nullable Throwable t) {
+            logger.debug(message, t);
+          }
+
+          @Override
+          public void error(@NonNls String message, @Nullable Throwable t, @NonNls String... details) {
+            logger.debug(message, t);
+          }
+
+          @Override
+          public void info(@NonNls String message) {
+            logger.info(message);
+          }
+
+          @Override
+          public void info(@NonNls String message, @Nullable Throwable t) {
+            logger.info(message, t);
+          }
+
+          @Override
+          public void warn(@NonNls String message, @Nullable Throwable t) {
+            logger.warn(message, t);
+          }
+
+          @Override
+          public void setLevel(Level level) {
+            logger.setLevel(level);
+          }
+        };
+      }
+    });
+  }
+
   private class ChannelRegistrar extends SimpleChannelUpstreamHandler {
     public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
       myAllOpenChannels.add(e.getChannel());
index c3c796f349de05d806bb66ff13507b50db264327..75756ad6f05e2b0a265b8887e4ca6e0fc80d850c 100644 (file)
@@ -172,9 +172,23 @@ class DependencyContext {
   public Logger<S> getLogger(final com.intellij.openapi.diagnostic.Logger log) {
     return new Logger<S>() {
       @Override
-      public void debug(S s) {
+      public void debug(String comment, S s) {
         if (log.isDebugEnabled()) {
-          log.debug(getValue(s));
+          log.debug(comment + getValue(s));
+        }
+      }
+
+      @Override
+      public void debug(String comment, String t) {
+        if (log.isDebugEnabled()){
+          log.debug(comment + t);
+        }
+      }
+
+      @Override
+      public void debug(String comment, boolean t) {
+        if (log.isDebugEnabled()) {
+          log.debug(comment + Boolean.toString(t));
         }
       }
     };
index 20ffdf19d8f4e92206994d454e83e9495d76406d..a409a4c9ec6f66438ba1c1bbfc183139de90a06f 100644 (file)
@@ -23,5 +23,7 @@ package org.jetbrains.ether.dependencyView;
  * To change this template use File | Settings | File Templates.
  */
 public interface Logger<T> {
-  void debug(T t);
+  void debug(String comment, T t);
+  void debug(String comment, String t);
+  void debug(String comment, boolean t);
 }
index 43bde0ea86f336d0af1b4b4fb297d0f918f9a196..16846ac8e8f2ebeed21a65ab654e601b0d5babcc 100644 (file)
@@ -1,13 +1,12 @@
 package org.jetbrains.ether.dependencyView;
 
+import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.io.FileUtil;
+import org.jetbrains.annotations.Nullable;
 import org.objectweb.asm.ClassReader;
 import org.objectweb.asm.Opcodes;
 
-import com.intellij.openapi.diagnostic.Logger;
-import org.jetbrains.annotations.*;
-
 import java.io.File;
 import java.io.IOException;
 import java.lang.annotation.ElementType;
@@ -22,7 +21,7 @@ import java.util.*;
  * To change this template use File | Settings | File Templates.
  */
 public class Mappings {
-  private final static Logger LOG = Logger.getInstance ("#org.jetbrains.ether.dependencyView.Mappings");
+  private final static Logger LOG = Logger.getInstance("#org.jetbrains.ether.dependencyView.Mappings");
 
   private final static String CLASS_TO_SUBCLASSES = "classToSubclasses.tab";
   private final static String CLASS_TO_CLASS = "classToClass.tab";
@@ -38,12 +37,20 @@ public class Mappings {
   private DependencyContext myContext;
   private org.jetbrains.ether.dependencyView.Logger<DependencyContext.S> myDebugS;
 
-  private void debug(final String s) {
+  private static void debug(final String s) {
     LOG.debug(s);
   }
 
-  private void debug(final DependencyContext.S s) {
-    myDebugS.debug(s);
+  private void debug(final String comment, final DependencyContext.S s) {
+    myDebugS.debug(comment, s);
+  }
+
+  private void debug(final String comment, final String s) {
+    myDebugS.debug(comment, s);
+  }
+
+  private void debug(final String comment, final boolean s) {
+    myDebugS.debug(comment, s);
   }
 
   private MultiMaplet<DependencyContext.S, DependencyContext.S> myClassToSubclasses;
@@ -534,16 +541,25 @@ public class Mappings {
                           final Collection<UsageRepr.Usage> affectedUsages,
                           final Collection<DependencyContext.S> dependants,
                           final boolean usages) {
+      debug("Affecting subclasses of class: ", className);
+
       final DependencyContext.S fileName = myClassToSourceFile.get(className);
 
       if (fileName == null) {
+        debug("No source file detected for class ", className);
+        debug("End of affectSubclasses");
         return;
       }
 
+      debug("Source file name: ", fileName);
+
       if (usages) {
+        debug("Class usages affection requested");
+
         final ClassRepr classRepr = reprByName(className);
 
         if (classRepr != null) {
+          debug("Added class usage for ", classRepr.name);
           affectedUsages.add(classRepr.createUsage());
         }
       }
@@ -579,6 +595,7 @@ public class Mappings {
           dependents.addAll(deps);
         }
 
+        debug("Affect field usage referenced of class ", p);
         affectedUsages
           .add(rootUsage instanceof UsageRepr.FieldAssignUsage ? field.createAssignUsage(myContext, p) : field.createUsage(myContext, p));
       }
@@ -598,6 +615,8 @@ public class Mappings {
           dependents.addAll(deps);
         }
 
+        debug("Affect method usage referenced of class ", p);
+
         affectedUsages
           .add(rootUsage instanceof UsageRepr.MetaMethodUsage ? method.createMetaUsage(myContext, p) : method.createUsage(myContext, p));
       }
@@ -730,32 +749,38 @@ public class Mappings {
 
     // Public branch --- hopeless
     if ((member.access & Opcodes.ACC_PUBLIC) > 0) {
-      debug("Switched to non-incremental mode");
+      debug("Public access, switching to a non-incremental mode");
       return false;
     }
 
     // Protected branch
     if ((member.access & Opcodes.ACC_PROTECTED) > 0) {
-      debug("Softening non-incremental decision: adding all relevant subclasses for a recompilation");
+      debug("Protected access, softening non-incremental decision: adding all relevant subclasses for a recompilation");
+      debug("Root class: ", owner);
 
       final Collection<DependencyContext.S> propagated = self.propagateFieldAccess(isField ? member.name : myContext.get(""), owner);
 
       for (DependencyContext.S className : propagated) {
-        affectedFiles.add(new File(myContext.getValue(myClassToSourceFile.get(className))));
+        final String fileName = myContext.getValue(myClassToSourceFile.get(className));
+        debug("Adding ", fileName);
+        affectedFiles.add(new File(fileName));
       }
     }
 
-    debug("Softening non-incremental decision: adding all package classes for a recompilation");
-
     final String packageName = ClassRepr.getPackageName(myContext.getValue(isField ? owner : member.name));
 
+    debug("Softening non-incremental decision: adding all package classes for a recompilation");
+    debug("Package name: ", packageName);
+
     // Package-local branch    
     for (Map.Entry<DependencyContext.S, DependencyContext.S> e : myClassToSourceFile.entrySet()) {
       final DependencyContext.S className = e.getKey();
       final DependencyContext.S fileName = e.getValue();
 
       if (ClassRepr.getPackageName(myContext.getValue(className)).equals(packageName)) {
-        affectedFiles.add(new File(myContext.getValue(fileName)));
+        final String f = myContext.getValue(fileName);
+        debug("Adding: ", f);
+        affectedFiles.add(new File(f));
       }
     }
 
@@ -767,6 +792,8 @@ public class Mappings {
                                final Collection<File> filesToCompile,
                                final Collection<File> compiledFiles,
                                final Collection<File> affectedFiles) {
+    debug("Begin of Differentiate:");
+
     delta.compensateRemovedContent(filesToCompile);
 
     final Util u = new Util(delta);
@@ -798,14 +825,12 @@ public class Mappings {
 
       final Difference.Specifier<ClassRepr> classDiff = Difference.make(pastClasses, classes);
 
-      debug("Processing changed classes");
-
+      debug("Processing changed classes:");
       for (Pair<ClassRepr, Difference> changed : classDiff.changed()) {
         final ClassRepr it = changed.first;
         final ClassRepr.Diff diff = (ClassRepr.Diff)changed.second;
 
-        debug("Changed: ");
-        debug(it.name);
+        debug("Changed: ", it.name);
 
         final int addedModifiers = diff.addedModifiers();
         final int removedModifiers = diff.removedModifiers();
@@ -815,24 +840,34 @@ public class Mappings {
         final boolean signatureChanged = (diff.base() & Difference.SIGNATURE) > 0;
 
         if (superClassChanged || interfacesChanged || signatureChanged) {
+          debug("Superclass changed: ", superClassChanged);
+          debug("Interfaces changed: ", interfacesChanged);
+          debug("Signature changed ", signatureChanged);
+
           final boolean extendsChanged = superClassChanged && !diff.extendsAdded();
           final boolean interfacesRemoved = interfacesChanged && !diff.interfaces().removed().isEmpty();
 
+          debug("Extends changed: ", extendsChanged);
+          debug("Interfaces removed: ", interfacesRemoved);
+
           u.affectSubclasses(it.name, affectedFiles, affectedUsages, dependants, extendsChanged || interfacesRemoved || signatureChanged);
         }
 
         if ((diff.addedModifiers() & Opcodes.ACC_INTERFACE) > 0 || (diff.removedModifiers() & Opcodes.ACC_INTERFACE) > 0) {
+          debug("Class-to-interface or interface-to-class conversion detected, added class usage to affected usages");
           affectedUsages.add(it.createUsage());
         }
 
         if (it.isAnnotation() && it.policy == RetentionPolicy.SOURCE) {
           debug("Annotation, retention policy = SOURCE => a switch to non-incremental mode requested");
           if (!incrementalDecision(it.outerClassName, it, affectedFiles)) {
+            debug("End of Differentiate, returning false");
             return false;
           }
         }
 
         if ((addedModifiers & Opcodes.ACC_PROTECTED) > 0) {
+          debug("Introduction of 'protected' modifier detected, adding class usage + inheritance constraint to affected usages");
           final UsageRepr.Usage usage = it.createUsage();
 
           affectedUsages.add(usage);
@@ -840,6 +875,7 @@ public class Mappings {
         }
 
         if (diff.packageLocalOn()) {
+          debug("Introduction of 'package local' access detected, adding class usage + package constraint to affected usages");
           final UsageRepr.Usage usage = it.createUsage();
 
           affectedUsages.add(usage);
@@ -847,54 +883,64 @@ public class Mappings {
         }
 
         if ((addedModifiers & Opcodes.ACC_FINAL) > 0 || (addedModifiers & Opcodes.ACC_PRIVATE) > 0) {
+          debug("Introduction of 'private' or 'final' modifier(s) detected, adding class usage to affected usages");
           affectedUsages.add(it.createUsage());
         }
 
-        if ((addedModifiers & Opcodes.ACC_ABSTRACT) > 0) {
-          affectedUsages.add(UsageRepr.createClassNewUsage(myContext, it.name));
-        }
-
-        if ((addedModifiers & Opcodes.ACC_STATIC) > 0 ||
-            (removedModifiers & Opcodes.ACC_STATIC) > 0 ||
-            (addedModifiers & Opcodes.ACC_ABSTRACT) > 0) {
+        if ((addedModifiers & Opcodes.ACC_ABSTRACT) > 0 || (addedModifiers & Opcodes.ACC_STATIC) > 0) {
+          debug("Introduction of 'abstract' or 'static' modifier(s) detected, adding class new usage to affected usages");
           affectedUsages.add(UsageRepr.createClassNewUsage(myContext, it.name));
         }
 
         if (it.isAnnotation()) {
+          debug("Class is annotation, performing annotation-specific analysis");
+
           if (diff.retentionChanged()) {
+            debug("Retention policy change detected, adding class usage to affected usages");
             affectedUsages.add(it.createUsage());
           }
           else {
             final Collection<ElementType> removedtargets = diff.targets().removed();
 
             if (removedtargets.contains(ElementType.LOCAL_VARIABLE)) {
-              debug("Annotation, removed target contains LOCAL_VARIABLE => a switch to non-incremental mode requested");
+              debug("Removed target contains LOCAL_VARIABLE => a switch to non-incremental mode requested");
               if (!incrementalDecision(it.outerClassName, it, affectedFiles)) {
+                debug("End of Differentiate, returning false");
                 return false;
               }
             }
 
             if (!removedtargets.isEmpty()) {
+              debug("Removed some annotation targets, adding annotation query");
               annotationQuery.add((UsageRepr.AnnotationUsage)UsageRepr
                 .createAnnotationUsage(myContext, TypeRepr.createClassType(myContext, it.name), null, removedtargets));
             }
 
             for (MethodRepr m : diff.methods().added()) {
               if (!m.hasValue()) {
+                debug("Added method with no default value: ", m.name);
+                debug("Adding class usage to affected usages");
                 affectedUsages.add(it.createUsage());
               }
             }
           }
+
+          debug("End of annotation-specific analysis");
         }
 
+        debug("Processing added methods: ");
         for (MethodRepr m : diff.methods().added()) {
+          debug("Method: ", m.name);
+
           if (it.isAnnotation()) {
+            debug("Class is annotation, skipping method analysis");
             continue;
           }
 
           if ((it.access & Opcodes.ACC_INTERFACE) > 0 ||
               (it.access & Opcodes.ACC_ABSTRACT) > 0 ||
               (m.access & Opcodes.ACC_ABSTRACT) > 0) {
+            debug("Class is abstract, or is interface, or added method in abstract => affecting all subclasses");
             u.affectSubclasses(it.name, affectedFiles, affectedUsages, dependants, false);
           }
 
@@ -908,6 +954,7 @@ public class Mappings {
             }
             else {
               propagated = u.propagateMethodAccess(m.name, it.name);
+              debug("Conservative case on overriding methods, affecting method usages");
               u.affectMethodUsages(m, propagated, m.createMetaUsage(myContext, it.name), affectedUsages, dependants);
             }
           }
@@ -924,10 +971,12 @@ public class Mappings {
 
             for (MethodRepr mm : lessSpecific) {
               if (!mm.equals(m)) {
+                debug("Found less specific method, affecting method usages");
                 u.affectMethodUsages(mm, propagated, mm.createUsage(myContext, it.name), affectedUsages, dependants);
               }
             }
 
+            debug("Processing affected by specificity methods");
             for (Pair<MethodRepr, ClassRepr> p : affectedMethods) {
               final MethodRepr mm = p.first;
               final ClassRepr cc = p.second;
@@ -936,7 +985,12 @@ public class Mappings {
 
               }
               else {
+                debug("Method: ", mm.name);
+                debug("Class : ", cc.name);
+
                 if (overrides.satisfy(mm)) {
+                  debug("Current method overrides that found");
+
                   final Option<Boolean> subtypeOf = u.isSubtypeOf(mm.type, m.type);
 
                   if (weakerAccess(mm.access, m.access) ||
@@ -949,11 +1003,15 @@ public class Mappings {
                     final DependencyContext.S file = myClassToSourceFile.get(cc.name);
 
                     if (file != null) {
-                      affectedFiles.add(new File(myContext.getValue(file)));
+                      final String f = myContext.getValue(file);
+                      debug("Complex condition is satisfied, affecting file ", f);
+                      affectedFiles.add(new File(f));
                     }
                   }
                 }
                 else {
+                  debug("Current method does not override that found");
+
                   final Collection<DependencyContext.S> yetPropagated = self.propagateMethodAccess(mm.name, cc.name);
                   final Collection<DependencyContext.S> deps = myClassToClassDependency.get(cc.name);
 
@@ -961,6 +1019,7 @@ public class Mappings {
                     dependants.addAll(deps);
                   }
 
+                  debug("Affecting method usages for that found");
                   u.affectMethodUsages(mm, yetPropagated, mm.createUsage(myContext, cc.name), affectedUsages, dependants);
                 }
               }
@@ -977,19 +1036,26 @@ public class Mappings {
                   final DependencyContext.S outerClass = r.outerClassName;
 
                   if (u.methodVisible(outerClass, m)) {
-                    affectedFiles.add(new File(myContext.getValue(sourceFileName)));
+                    final String f = myContext.getValue(sourceFileName);
+                    debug("Affecting file due to local overriding: ", f);
+                    affectedFiles.add(new File(f));
                   }
                 }
               }
             }
           }
         }
+        debug("End of added methods processing");
 
+        debug("Processing removed methods:");
         for (MethodRepr m : diff.methods().removed()) {
+          debug("Method ", m.name);
+
           final Collection<Pair<MethodRepr, ClassRepr>> overridenMethods = u.findOverridenMethods(m, it);
           final Collection<DependencyContext.S> propagated = u.propagateMethodAccess(m.name, it.name);
 
           if (overridenMethods.size() == 0) {
+            debug("No overridden methods found, affecting method usages");
             u.affectMethodUsages(m, propagated, m.createUsage(myContext, it.name), affectedUsages, dependants);
           }
           else {
@@ -1006,6 +1072,7 @@ public class Mappings {
             }
 
             if (!clear) {
+              debug("No clearly overridden methods found, affecting method usages");
               u.affectMethodUsages(m, propagated, m.createUsage(myContext, it.name), affectedUsages, dependants);
             }
           }
@@ -1046,21 +1113,31 @@ public class Mappings {
                   final DependencyContext.S source = myClassToSourceFile.get(p);
 
                   if (source != null) {
-                    affectedFiles.add(new File(myContext.getValue(source)));
+                    final String f = myContext.getValue(source);
+                    debug(
+                      "Removed method is not abstract & is overrides some abstract method which is not then over-overriden in subclass ",
+                      p);
+                    debug("Affecting subclass source file ", f);
+                    affectedFiles.add(new File(f));
                   }
                 }
               }
             }
           }
         }
+        debug("End of removed methods processing");
 
+        debug("Processing changed methods:");
         for (Pair<MethodRepr, Difference> mr : diff.methods().changed()) {
           final MethodRepr m = mr.first;
           final MethodRepr.Diff d = (MethodRepr.Diff)mr.second;
           final boolean throwsChanged = (d.exceptions().added().size() > 0) || (d.exceptions().changed().size() > 0);
 
+          debug("Method: ", m.name);
+
           if (it.isAnnotation()) {
             if (d.defaultRemoved()) {
+              debug("Class is annotation, default value is removed => adding annotation query");
               final List<DependencyContext.S> l = new LinkedList<DependencyContext.S>();
               l.add(m.name);
               annotationQuery.add((UsageRepr.AnnotationUsage)UsageRepr
@@ -1076,6 +1153,7 @@ public class Mappings {
             final Set<UsageRepr.Usage> usages = new HashSet<UsageRepr.Usage>();
 
             if (d.packageLocalOn()) {
+              debug("Method became package-local, affecting method usages outside the package");
               u.affectMethodUsages(m, propagated, m.createUsage(myContext, it.name), usages, dependants);
 
               for (UsageRepr.Usage usage : usages) {
@@ -1089,6 +1167,7 @@ public class Mappings {
 
             if ((d.base() & Difference.TYPE) > 0 || (d.base() & Difference.SIGNATURE) > 0 || throwsChanged) {
               if (!affected) {
+                debug("Return type, throws list or signature changed --- affecting method usages");
                 u.affectMethodUsages(m, propagated, m.createUsage(myContext, it.name), usages, dependants);
                 affectedUsages.addAll(usages);
               }
@@ -1098,11 +1177,13 @@ public class Mappings {
                   (d.removedModifiers() & Opcodes.ACC_STATIC) > 0 ||
                   (d.addedModifiers() & Opcodes.ACC_PRIVATE) > 0) {
                 if (!affected) {
+                  debug("Added static or private specifier or removed static specifier --- affecting method usages");
                   u.affectMethodUsages(m, propagated, m.createUsage(myContext, it.name), usages, dependants);
                   affectedUsages.addAll(usages);
                 }
 
                 if ((d.addedModifiers() & Opcodes.ACC_STATIC) > 0) {
+                  debug("Added static specifier --- affecting subclasses");
                   u.affectSubclasses(it.name, affectedFiles, affectedUsages, dependants, false);
                 }
               }
@@ -1110,11 +1191,13 @@ public class Mappings {
                 if ((d.addedModifiers() & Opcodes.ACC_FINAL) > 0 ||
                     (d.addedModifiers() & Opcodes.ACC_PUBLIC) > 0 ||
                     (d.addedModifiers() & Opcodes.ACC_ABSTRACT) > 0) {
+                  debug("Added final, public or abstract specifier --- affecting subclasses");
                   u.affectSubclasses(it.name, affectedFiles, affectedUsages, dependants, false);
                 }
 
                 if ((d.addedModifiers() & Opcodes.ACC_PROTECTED) > 0 && !((d.removedModifiers() & Opcodes.ACC_PRIVATE) > 0)) {
                   if (!constrained) {
+                    debug("Added public or package-local method became protected --- affect method usages with protected constraint");
                     if (!affected) {
                       u.affectMethodUsages(m, propagated, m.createUsage(myContext, it.name), usages, dependants);
                       affectedUsages.addAll(usages);
@@ -1129,10 +1212,14 @@ public class Mappings {
             }
           }
         }
+        debug("End of changed methods processing");
 
         final int mask = Opcodes.ACC_STATIC | Opcodes.ACC_FINAL;
 
+        debug("Processing added fields");
         for (FieldRepr f : diff.fields().added()) {
+          debug("Field: ", f.name);
+
           final boolean fPrivate = (f.access & Opcodes.ACC_PRIVATE) > 0;
           final boolean fProtected = (f.access & Opcodes.ACC_PROTECTED) > 0;
           final boolean fPublic = (f.access & Opcodes.ACC_PUBLIC) > 0;
@@ -1141,32 +1228,34 @@ public class Mappings {
           if (!fPrivate) {
             final Collection<DependencyContext.S> subClasses = getAllSubclasses(it.name);
 
-            if (subClasses != null) {
-              for (final DependencyContext.S subClass : subClasses) {
-                final ClassRepr r = u.reprByName(subClass);
-                final DependencyContext.S sourceFileName = myClassToSourceFile.get(subClass);
+            for (final DependencyContext.S subClass : subClasses) {
+              final ClassRepr r = u.reprByName(subClass);
+              final DependencyContext.S sourceFileName = myClassToSourceFile.get(subClass);
 
-                if (r != null && sourceFileName != null) {
-                  if (r.isLocal) {
-                    affectedFiles.add(new File(myContext.getValue(sourceFileName)));
-                  }
-                  else {
-                    final DependencyContext.S outerClass = r.outerClassName;
+              if (r != null && sourceFileName != null) {
+                if (r.isLocal) {
+                  debug("Affecting local subclass (introduced field can potentially hide surrounding method parameters/local variables): ",
+                        sourceFileName);
+                  affectedFiles.add(new File(myContext.getValue(sourceFileName)));
+                }
+                else {
+                  final DependencyContext.S outerClass = r.outerClassName;
 
-                    if (!empty(outerClass) && u.fieldVisible(outerClass, f)) {
-                      affectedFiles.add(new File(myContext.getValue(sourceFileName)));
-                    }
+                  if (!empty(outerClass) && u.fieldVisible(outerClass, f)) {
+                    debug("Affecting inner subclass (introduced field can potentially hide surrounding class fields): ", sourceFileName);
+                    affectedFiles.add(new File(myContext.getValue(sourceFileName)));
                   }
                 }
+              }
 
-                final Collection<DependencyContext.S> propagated = u.propagateFieldAccess(f.name, subClass);
-                u.affectFieldUsages(f, propagated, f.createUsage(myContext, subClass), affectedUsages, dependants);
+              debug("Affecting field usages referenced from subclass ", subClass);
+              final Collection<DependencyContext.S> propagated = u.propagateFieldAccess(f.name, subClass);
+              u.affectFieldUsages(f, propagated, f.createUsage(myContext, subClass), affectedUsages, dependants);
 
-                final Collection<DependencyContext.S> deps = myClassToClassDependency.get(subClass);
+              final Collection<DependencyContext.S> deps = myClassToClassDependency.get(subClass);
 
-                if (deps != null) {
-                  dependants.addAll(deps);
-                }
+              if (deps != null) {
+                dependants.addAll(deps);
               }
             }
           }
@@ -1186,6 +1275,7 @@ public class Mappings {
               final Collection<DependencyContext.S> propagated = o.propagateFieldAccess(ff.name, cc.name);
               final Set<UsageRepr.Usage> localUsages = new HashSet<UsageRepr.Usage>();
 
+              debug("Affecting usages of overridden field in class ", cc.name);
               u.affectFieldUsages(ff, propagated, ff.createUsage(myContext, cc.name), localUsages, dependants);
 
               if (fPrivate || (fPublic && (ffPublic || ffPLocal)) || (fProtected && ffProtected) || (fPLocal && ffPLocal)) {
@@ -1214,16 +1304,16 @@ public class Mappings {
             }
           }
         }
+        debug("End of added fields processing");
 
-        debug("Processing removed fields");
-
+        debug("Processing removed fields:");
         for (FieldRepr f : diff.fields().removed()) {
-          debug("Field ");
-          debug(f.name);
+          debug("Field: ", it.name);
 
           if ((f.access & Opcodes.ACC_PRIVATE) == 0 && (f.access & mask) == mask && f.hasValue()) {
             debug("Field had value and was (non-private) final static => a switch to non-incremental mode requested");
             if (!incrementalDecision(it.name, f, affectedFiles)) {
+              debug("End of Differentiate, returning false");
               return false;
             }
           }
@@ -1231,20 +1321,20 @@ public class Mappings {
           final Collection<DependencyContext.S> propagated = u.propagateFieldAccess(f.name, it.name);
           u.affectFieldUsages(f, propagated, f.createUsage(myContext, it.name), affectedUsages, dependants);
         }
+        debug("End of removed fields processing");
 
-        debug("Processing changed fields");
-
+        debug("Processing changed fields:");
         for (Pair<FieldRepr, Difference> f : diff.fields().changed()) {
           final Difference d = f.second;
           final FieldRepr field = f.first;
 
-          debug("Field ");
-          debug(field.name);
+          debug("Field: ", it.name);
 
           if ((field.access & Opcodes.ACC_PRIVATE) == 0 && (field.access & mask) == mask) {
             if ((d.base() & Difference.ACCESS) > 0 || (d.base() & Difference.VALUE) > 0) {
               debug("Inline field changed it's access or value => a switch to non-incremental mode requested");
-              if (!incrementalDecision(it.name, field, affectedFiles)){
+              if (!incrementalDecision(it.name, field, affectedFiles)) {
+                debug("End of Differentiate, returning false");
                 return false;
               }
             }
@@ -1254,6 +1344,7 @@ public class Mappings {
             final Collection<DependencyContext.S> propagated = u.propagateFieldAccess(field.name, it.name);
 
             if ((d.base() & Difference.TYPE) > 0 || (d.base() & Difference.SIGNATURE) > 0) {
+              debug("Type or signature changed --- affecting field usages");
               u.affectFieldUsages(field, propagated, field.createUsage(myContext, it.name), affectedUsages, dependants);
             }
             else if ((d.base() & Difference.ACCESS) > 0) {
@@ -1261,7 +1352,7 @@ public class Mappings {
                   (d.removedModifiers() & Opcodes.ACC_STATIC) > 0 ||
                   (d.addedModifiers() & Opcodes.ACC_PRIVATE) > 0 ||
                   (d.addedModifiers() & Opcodes.ACC_VOLATILE) > 0) {
-
+                debug("Added/removed static modifier or added private/volatile modifier --- affecting field usages");
                 u.affectFieldUsages(field, propagated, field.createUsage(myContext, it.name), affectedUsages, dependants);
               }
               else {
@@ -1269,12 +1360,14 @@ public class Mappings {
                 final Set<UsageRepr.Usage> usages = new HashSet<UsageRepr.Usage>();
 
                 if ((d.addedModifiers() & Opcodes.ACC_FINAL) > 0) {
+                  debug("Added final modifier --- affecting field assign usages");
                   u.affectFieldUsages(field, propagated, field.createAssignUsage(myContext, it.name), usages, dependants);
                   affectedUsages.addAll(usages);
                   affected = true;
                 }
 
                 if ((d.removedModifiers() & Opcodes.ACC_PUBLIC) > 0) {
+                  debug("Removed public modifier, affecting field usages with appropriate constraint");
                   if (!affected) {
                     u.affectFieldUsages(field, propagated, field.createUsage(myContext, it.name), usages, dependants);
                     affectedUsages.addAll(usages);
@@ -1293,12 +1386,18 @@ public class Mappings {
             }
           }
         }
+        debug("End of changed fields processing");
       }
+      debug("End of changed classes processing");
 
+      debug("Processing removed classes:");
       for (ClassRepr c : classDiff.removed()) {
+        debug("Adding usages of class ", c.name);
         affectedUsages.add(c.createUsage());
       }
+      debug("End of removed classes processing.");
 
+      debug("Processing added classes:");
       for (ClassRepr c : classDiff.added()) {
         final Collection<DependencyContext.S> depClasses = myClassToClassDependency.get(c.name);
 
@@ -1307,12 +1406,16 @@ public class Mappings {
             final DependencyContext.S fName = myClassToSourceFile.get(depClass);
 
             if (fName != null) {
-              affectedFiles.add(new File(myContext.getValue(fName)));
+              final String f = myContext.getValue(fName);
+              debug("Adding dependent file ", f);
+              affectedFiles.add(new File(f));
             }
           }
         }
       }
+      debug("End of added classes processing.");
 
+      debug("Checking dependent files:");
       if (dependants != null) {
         final Set<DependencyContext.S> dependentFiles = new HashSet<DependencyContext.S>();
 
@@ -1332,6 +1435,8 @@ public class Mappings {
             continue filewise;
           }
 
+          debug("Dependent file: ", depFile);
+
           final Collection<UsageRepr.Cluster> depClusters = mySourceFileToUsages.get(depFile);
 
           for (UsageRepr.Cluster depCluster : depClusters) {
@@ -1347,6 +1452,7 @@ public class Mappings {
                   final Util.UsageConstraint constraint = usageConstraints.get(usage);
 
                   if (constraint == null) {
+                    debug("Added file with no constraints");
                     affectedFiles.add(theFile);
                     continue filewise;
                   }
@@ -1354,6 +1460,7 @@ public class Mappings {
                     final Set<DependencyContext.S> residenceClasses = depCluster.getResidence(usage);
                     for (DependencyContext.S residentName : residenceClasses) {
                       if (constraint.checkResidence(residentName)) {
+                        debug("Added file with satisfied constraint");
                         affectedFiles.add(theFile);
                         continue filewise;
                       }
@@ -1369,6 +1476,7 @@ public class Mappings {
                 for (UsageRepr.Usage usage : annotationUsages) {
                   for (UsageRepr.AnnotationUsage query : annotationQuery) {
                     if (query.satisfies(usage)) {
+                      debug("Added file due to annotation query");
                       affectedFiles.add(theFile);
                       continue filewise;
                     }
@@ -1381,6 +1489,13 @@ public class Mappings {
       }
     }
 
+    if (removed != null) {
+      for (String r : removed) {
+        affectedFiles.remove(new File(r));
+      }
+    }
+
+    debug("End of Differentiate, returning true");
     return true;
   }
 
@@ -1425,7 +1540,6 @@ public class Mappings {
         }
       }
 
-
       myClassToSubclasses.putAll(delta.myClassToSubclasses);
       mySourceFileToClasses.putAll(delta.mySourceFileToClasses);
       mySourceFileToUsages.putAll(delta.mySourceFileToUsages);
diff --git a/lib/netty-3.2.5.Final.jar b/lib/netty-3.2.5.Final.jar
deleted file mode 100644 (file)
index f3b79fc..0000000
Binary files a/lib/netty-3.2.5.Final.jar and /dev/null differ
diff --git a/lib/netty-3.3.0.Final.jar b/lib/netty-3.3.0.Final.jar
new file mode 100644 (file)
index 0000000..7929a27
Binary files /dev/null and b/lib/netty-3.3.0.Final.jar differ
index 6e5ed206d18fe2100dfcd1e7cbad698ea11c8196..5a2fd8ed757e0ecf4e3d8950cc294f58dc67dc36 100644 (file)
@@ -44,5 +44,5 @@ xmlrpc-2.0.jar
 xpp3-1.1.4-min.jar
 xstream.jar
 swingx-core-1.6.2.jar
-netty-3.2.5.Final.jar
+netty-3.3.0.Final.jar
 protobuf-2.3.0.jar
diff --git a/lib/src/netty-3.2.5.Final-sources.jar b/lib/src/netty-3.2.5.Final-sources.jar
deleted file mode 100644 (file)
index cb6cb9b..0000000
Binary files a/lib/src/netty-3.2.5.Final-sources.jar and /dev/null differ
diff --git a/lib/src/netty-3.3.0.Final-sources.jar b/lib/src/netty-3.3.0.Final-sources.jar
new file mode 100644 (file)
index 0000000..40d5a4e
Binary files /dev/null and b/lib/src/netty-3.3.0.Final-sources.jar differ
diff --git a/platform/icons/src/actions/move-to-button-top.png b/platform/icons/src/actions/move-to-button-top.png
new file mode 100644 (file)
index 0000000..4516cba
Binary files /dev/null and b/platform/icons/src/actions/move-to-button-top.png differ
diff --git a/platform/icons/src/actions/move-to-button.png b/platform/icons/src/actions/move-to-button.png
new file mode 100644 (file)
index 0000000..c634775
Binary files /dev/null and b/platform/icons/src/actions/move-to-button.png differ
index e236c63676ecb995ea264c8201ddc51f5a2db5ea..1251e87e2f67eac13a9c5e26ee7d8686ad25eed8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2012 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -36,11 +36,11 @@ public class DefaultExecutionResult implements ExecutionResult {
   private AnAction[] myRestartActions;
   private final List<AnAction> myStopActions = new ArrayList<AnAction>();
 
-  public DefaultExecutionResult(final ExecutionConsole console, final ProcessHandler processHandler) {
+  public DefaultExecutionResult(final ExecutionConsole console, @NotNull final ProcessHandler processHandler) {
     this(console, processHandler, AnAction.EMPTY_ARRAY);
   }
 
-  public DefaultExecutionResult(final ExecutionConsole console, final ProcessHandler processHandler, final AnAction... actions) {
+  public DefaultExecutionResult(final ExecutionConsole console, @NotNull final ProcessHandler processHandler, final AnAction... actions) {
     myConsole = console;
     myProcessHandler = processHandler;
     myActions = actions;
index 869491c8a685f3ab1ac7a258a9495c93ae5a0702..06c8cd55a7d7b75de4ac13cc04308b9490686fe2 100644 (file)
@@ -17,7 +17,6 @@
 package com.intellij.execution.ui.actions;
 
 import com.intellij.execution.ui.layout.Grid;
-import com.intellij.execution.ui.layout.GridCell;
 import com.intellij.execution.ui.layout.Tab;
 import com.intellij.execution.ui.layout.ViewContext;
 import com.intellij.openapi.actionSystem.AnActionEvent;
@@ -74,11 +73,6 @@ public abstract class BaseViewAction extends DumbAwareAction {
     return e.getData(ViewContext.CONTENT_KEY);
   }
 
-  protected static boolean isDetached(ViewContext context, Content content) {
-    final GridCell cell = context.findCellFor(content);
-    return cell != null && cell.isDetached();
-  }
-
   @Nullable
   protected static Tab getTabFor(final ViewContext context, final Content[] content) {
     Grid grid = context.findGridFor(content[0]);
index e37c46a19083b023b35c54715caea1c40a671dc7..b9c7b21da1975db15fe5cd10cab5eba2472b7a6e 100644 (file)
@@ -72,12 +72,6 @@ public interface CellTransform {
 
   interface Facade {
     void minimize(Content content, Restore restore);
-
-    void moveToTab(final Content content);
-
-    void moveToGrid(final Content content);
-
-    Restore detach(final Content[] content);
   }
  
 }
index 2201bd8d6699a34d927bfae9273f4e30863e8095..ebcbdd6a2a512b97766f0995caf63f4b588af4f4 100644 (file)
 
 package com.intellij.execution.ui.layout;
 
-import com.intellij.openapi.util.ActionCallback;
 import com.intellij.ui.content.Content;
 
 public interface GridCell {
-  boolean isDetached();
-
   int getContentCount();
 
-  void attach();
-
   void minimize(final Content content);
-
-  ActionCallback detach();
 }
\ No newline at end of file
index c208e3c49b1f49d4407b95748669004e52247298..686162a17391456f081c2efd0591d9221ba76f43 100644 (file)
@@ -22,6 +22,7 @@ public interface Tab {
   void setDetached(final PlaceInGrid placeInGrid, final boolean detached);
 
   int getIndex();
+  int getDefaultIndex();
 
   boolean isDetached(final PlaceInGrid placeInGrid);
 }
\ No newline at end of file
index 761a1b50225047179244daf8f005c206ec6b58e5..c81532e8105fba6e9e2992c89b70ed4fe8c0662d 100644 (file)
@@ -32,4 +32,8 @@ public interface View {
   void assignTab(Tab tab);
 
   void setTabIndex(int tabIndex);
+
+  int getWindow();
+
+  void setWindow(int windowNumber);
 }
\ No newline at end of file
index 3c87dda6701c2297533ad74e470ff9e5ba2e7c14..8f777e4864c9d2f648777d0a1e095a9ee6ba0157 100644 (file)
@@ -51,29 +51,29 @@ public class DefaultWordsScanner implements WordsScanner {
 
   public void processWords(CharSequence fileText, Processor<WordOccurrence> processor) {
     myLexer.start(fileText);
-    WordOccurrence occurence = null; // shared occurence
+    WordOccurrence occurrence = null; // shared occurrence
 
     while (myLexer.getTokenType() != null) {
       final IElementType type = myLexer.getTokenType();
       if (myIdentifierTokenSet.contains(type)) {
-        if (occurence == null) {
-          occurence = new WordOccurrence(fileText, myLexer.getTokenStart(), myLexer.getTokenEnd(), WordOccurrence.Kind.CODE);
+        if (occurrence == null) {
+          occurrence = new WordOccurrence(fileText, myLexer.getTokenStart(), myLexer.getTokenEnd(), WordOccurrence.Kind.CODE);
         }
         else {
-          occurence.init(fileText, myLexer.getTokenStart(), myLexer.getTokenEnd(), WordOccurrence.Kind.CODE);
+          occurrence.init(fileText, myLexer.getTokenStart(), myLexer.getTokenEnd(), WordOccurrence.Kind.CODE);
         }
-        if (!processor.process(occurence)) return;
+        if (!processor.process(occurrence)) return;
       }
       else if (myCommentTokenSet.contains(type)) {
-        if (!stripWords(processor, fileText,myLexer.getTokenStart(),myLexer.getTokenEnd(), WordOccurrence.Kind.COMMENTS,occurence, false)) return;
+        if (!stripWords(processor, fileText,myLexer.getTokenStart(),myLexer.getTokenEnd(), WordOccurrence.Kind.COMMENTS,occurrence, false)) return;
       }
       else if (myLiteralTokenSet.contains(type)) {
-        if (!stripWords(processor, fileText, myLexer.getTokenStart(),myLexer.getTokenEnd(),WordOccurrence.Kind.LITERALS,occurence, myMayHaveFileRefsInLiterals)) return;
+        if (!stripWords(processor, fileText, myLexer.getTokenStart(),myLexer.getTokenEnd(),WordOccurrence.Kind.LITERALS,occurrence, myMayHaveFileRefsInLiterals)) return;
       }
       else {
         // process all word-like characters as words
         // Plugin writers may have (Maximka in JavaScript especially) some keyword token types omitted from the identifierTokenSet
-        if (!stripWords(processor, fileText, myLexer.getTokenStart(), myLexer.getTokenEnd(), WordOccurrence.Kind.CODE, occurence, false)) return;
+        if (!stripWords(processor, fileText, myLexer.getTokenStart(), myLexer.getTokenEnd(), WordOccurrence.Kind.CODE, occurrence, false)) return;
       }
       myLexer.advance();
     }
index ee1818ffa8454b1caf783bf7f0a55e8bad70e570..179f975b6ee9dfd21386c8a506ab7cbd773fb537 100644 (file)
@@ -112,6 +112,7 @@ public class AutoPopupController implements Disposable {
     Runnable request = new Runnable() {
       @Override
       public void run() {
+        if (myProject.isDefault()) return;
         CompletionAutoPopupHandler.runLaterWithCommitted(myProject, editor.getDocument(), new Runnable() {
           @Override
           public void run() {
index f4f219c30e12de491e0aa9541d179c96feb77402..dbe5d13a980b8734e22b8776fcaaa9a333867f38 100644 (file)
@@ -268,10 +268,14 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
     myScrollPane.setViewportBorder(JBScrollPane.createIndentBorder());
 
     final DefaultActionGroup actions = new DefaultActionGroup();
-    actions.add(new BackAction());
-    actions.add(new ForwardAction());
+    final BackAction back = new BackAction();
+    final ForwardAction forward = new ForwardAction();
+    actions.add(back);
+    actions.add(forward);
     actions.add(myExternalDocAction = new ExternalDocAction());
-
+    back.registerCustomShortcutSet(CustomShortcutSet.fromString("LEFT"), this);
+    forward.registerCustomShortcutSet(CustomShortcutSet.fromString("RIGHT"), this);
+    myExternalDocAction.registerCustomShortcutSet(CustomShortcutSet.fromString("UP"), this);
     if (additionalActions != null) {
       for (final AnAction action : additionalActions) {
         actions.add(action);
index c78850c2ca401febd5daa7fbd2cae1280108a509..d2672ff88fc1a292573569d6dbe87dd27b2f310d 100644 (file)
@@ -35,6 +35,7 @@ import com.intellij.openapi.extensions.Extensions;
 import com.intellij.openapi.project.DumbService;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Disposer;
+import com.intellij.ui.docking.DockManager;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -76,7 +77,7 @@ public class ExecutionManagerImpl extends ExecutionManager implements ProjectCom
 
   public RunContentManager getContentManager() {
     if (myContentManager == null) {
-      myContentManager = new RunContentManagerImpl(myProject);
+      myContentManager = new RunContentManagerImpl(myProject, DockManager.getInstance(myProject));
       Disposer.register(myProject, myContentManager);
     }
     return myContentManager;
index 7a42e42487ac3aac466588f32e013806299a3dbb..0a6f6b508feb346be8a7adf453ed766da98def00 100644 (file)
@@ -23,6 +23,7 @@ import com.intellij.execution.process.ProcessAdapter;
 import com.intellij.execution.process.ProcessEvent;
 import com.intellij.execution.process.ProcessHandler;
 import com.intellij.execution.runners.GenericProgramRunner;
+import com.intellij.execution.ui.layout.impl.DockableGridContainerFactory;
 import com.intellij.ide.DataManager;
 import com.intellij.ide.impl.ContentManagerWatcher;
 import com.intellij.openapi.Disposable;
@@ -47,6 +48,7 @@ import com.intellij.openapi.wm.ToolWindowManager;
 import com.intellij.openapi.wm.ex.ToolWindowManagerAdapter;
 import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
 import com.intellij.ui.content.*;
+import com.intellij.ui.docking.DockManager;
 import com.intellij.util.concurrency.Semaphore;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.containers.HashMap;
@@ -65,13 +67,17 @@ public class RunContentManagerImpl implements RunContentManager, Disposable {
   private static final Key<RunContentDescriptor> DESCRIPTOR_KEY = new Key<RunContentDescriptor>("Descriptor");
 
   private final Project myProject;
+  private DockableGridContainerFactory myContentFactory;
   private final Map<String, ContentManager> myToolwindowIdToContentManagerMap = new HashMap<String, ContentManager>();
 
   private final Map<RunContentListener, Disposable> myListeners = new HashMap<RunContentListener, Disposable>();
   private final LinkedList<String> myToolwindowIdZbuffer = new LinkedList<String>();
 
-  public RunContentManagerImpl(Project project) {
+  public RunContentManagerImpl(Project project, DockManager dockManager) {
     myProject = project;
+    myContentFactory = new DockableGridContainerFactory();
+    dockManager.register(DockableGridContainerFactory.TYPE, myContentFactory);
+    Disposer.register(myProject, myContentFactory);
   }
 
   public void init() {
diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/actions/AttachCellAction.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/actions/AttachCellAction.java
deleted file mode 100644 (file)
index 062347e..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.intellij.execution.ui.layout.actions;
-
-import com.intellij.execution.ui.actions.BaseViewAction;
-import com.intellij.execution.ui.layout.Grid;
-import com.intellij.execution.ui.layout.GridCell;
-import com.intellij.execution.ui.layout.ViewContext;
-import com.intellij.idea.ActionsBundle;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.ui.content.Content;
-
-public class AttachCellAction extends BaseViewAction {
-
-  protected void update(final AnActionEvent e, final ViewContext context, final Content[] content) {
-    if (content.length == 0 || !isDetached(context, content[0])) {
-      setEnabled(e, false);
-      return;
-    }
-
-    Grid grid = context.findGridFor(content[0]);
-
-    GridCell cell = grid.getCellFor(content[0]);
-    if (ViewContext.CELL_TOOLBAR_PLACE.equals(e.getPlace()) && content.length == 1) {
-      setEnabled(e, cell.getContentCount() == 1);
-    } else {
-      setEnabled(e, true);
-      if (cell.getContentCount() > 1) {
-        e.getPresentation().setText(ActionsBundle.message("action.Runner.AttachCells.text", cell.getContentCount()));
-      }
-    }
-  }
-
-  protected void actionPerformed(final AnActionEvent e, final ViewContext context, final Content[] content) {
-    context.findCellFor(content[0]).attach();
-  }
-}
index 98bfe91eecfef968d5c85a7b35a74ebc9684eaaf..cb18ab9d58400f59fd0a78b363925dc5d88d3369 100644 (file)
@@ -19,11 +19,19 @@ package com.intellij.execution.ui.layout.actions;
 import com.intellij.execution.ui.actions.BaseViewAction;
 import com.intellij.execution.ui.layout.ViewContext;
 import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.util.IconLoader;
 import com.intellij.ui.content.Content;
 
+import javax.swing.*;
+
 public class CloseViewAction extends BaseViewAction {
+  private static final Icon ICON = IconLoader.getIcon("/actions/closeNew.png");
+  private static final Icon HOVERED_ICON = IconLoader.getIcon("/actions/closeNewHovered.png");
+
   protected void update(final AnActionEvent e, final ViewContext context, final Content[] content) {
     setEnabled(e, isEnabled(context, content, e.getPlace()));
+    e.getPresentation().setIcon(ICON);
+    e.getPresentation().setHoveredIcon(HOVERED_ICON);
   }
 
   protected void actionPerformed(final AnActionEvent e, final ViewContext context, final Content[] content) {
diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/actions/DetachCellAction.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/actions/DetachCellAction.java
deleted file mode 100644 (file)
index 3121592..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.intellij.execution.ui.layout.actions;
-
-import com.intellij.execution.ui.actions.BaseViewAction;
-import com.intellij.execution.ui.layout.Grid;
-import com.intellij.execution.ui.layout.GridCell;
-import com.intellij.execution.ui.layout.ViewContext;
-import com.intellij.idea.ActionsBundle;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.ui.content.Content;
-
-public class DetachCellAction extends BaseViewAction {
-  protected void update(final AnActionEvent e, final ViewContext context, final Content[] content) {
-    if (content.length == 0 || isDetached(context, content[0])) {
-      setEnabled(e, false);
-      return;
-    }
-
-    Grid grid = context.findGridFor(content[0]);
-    if (grid == null) {
-      setEnabled(e, false);
-      return;
-    }
-
-    if (ViewContext.TAB_TOOLBAR_PLACE.equals(e.getPlace()) || (ViewContext.TAB_POPUP_PLACE.equals(e.getPlace()))) {
-      setEnabled(e, grid.getContents().size() == 1);
-    }
-    else {
-      GridCell cell = grid.getCellFor(content[0]);
-      if (ViewContext.CELL_TOOLBAR_PLACE.equals(e.getPlace()) && content.length == 1) {
-        setEnabled(e, cell.getContentCount() == 1);
-      } else {
-        setEnabled(e, true);
-        if (cell.getContentCount() > 1) {
-          e.getPresentation().setText(ActionsBundle.message("action.Runner.DetachCells.text", cell.getContentCount()));
-        }
-      }
-    }
-  }
-
-  protected void actionPerformed(final AnActionEvent e, final ViewContext context, final Content[] content) {
-    context.findCellFor(content[0]).detach();
-  }
-}
index 79982fb99f8b023b10eb0578e797e958d2f4927d..eaff624c45545ec46e0f37e75b060c39bcdb4a74 100644 (file)
@@ -20,12 +20,18 @@ import com.intellij.execution.ui.layout.Tab;
 import com.intellij.execution.ui.layout.ViewContext;
 import com.intellij.execution.ui.actions.BaseViewAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.util.IconLoader;
 import com.intellij.ui.content.Content;
 
+import javax.swing.*;
+
 public class MinimizeViewAction extends BaseViewAction {
+  private static final Icon ICON = IconLoader.getIcon("/actions/move-to-button.png");
+  private static final Icon ICON_TOP = IconLoader.getIcon("/actions/move-to-button-top.png");
 
   protected void update(final AnActionEvent e, final ViewContext context, final Content[] content) {
     setEnabled(e, isEnabled(context, content, e.getPlace()));
+    e.getPresentation().setIcon(ViewContext.TAB_TOOLBAR_PLACE.equals(e.getPlace()) ? ICON_TOP : ICON);
   }
 
   protected void actionPerformed(final AnActionEvent e, final ViewContext context, final Content[] content) {
@@ -39,19 +45,15 @@ public class MinimizeViewAction extends BaseViewAction {
       return false;
     }
 
-    if (isDetached(context, content[0])) {
-      return false;
-    }
-
     if (ViewContext.TAB_TOOLBAR_PLACE.equals(place) || ViewContext.TAB_POPUP_PLACE.equals(place)) {
-      return false;
-    }
-    else {
       Tab tab = getTabFor(context, content);
       if (tab == null) {
         return false;
       }
-      return tab.isDefault();
+      return !tab.isDefault();
+    }
+    else {
+      return getTabFor(context, content) != null;
     }
   }
 }
diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/actions/MoveToGridAction.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/actions/MoveToGridAction.java
deleted file mode 100644 (file)
index f66f501..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.intellij.execution.ui.layout.actions;
-
-import com.intellij.execution.ui.actions.BaseViewAction;
-import com.intellij.execution.ui.layout.Grid;
-import com.intellij.execution.ui.layout.Tab;
-import com.intellij.execution.ui.layout.ViewContext;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.ui.content.Content;
-
-public class MoveToGridAction extends BaseViewAction {
-  protected void update(final AnActionEvent e, final ViewContext context, final Content[] content) {
-    if (!context.isMoveToGridActionEnabled() || content.length != 1) {
-      setEnabled(e, false);
-      return;
-    }
-
-    if (isDetached(context, content[0])) {
-      setEnabled(e, false);
-      return;
-    }
-
-    Grid grid = context.findGridFor(content[0]);
-    if (grid == null) {
-      setEnabled(e, false);
-      return;
-    }
-    Tab tab = context.getTabFor(grid);
-    setEnabled(e, tab != null && !tab.isDefault() && grid.getContents().size() == 1);
-  }
-                     
-  protected void actionPerformed(final AnActionEvent e, final ViewContext context, final Content[] content) {
-    context.getCellTransform().moveToGrid(content[0]);
-  }
-}
diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/actions/MoveToTabAction.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/actions/MoveToTabAction.java
deleted file mode 100644 (file)
index bf23cb1..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.intellij.execution.ui.layout.actions;
-
-import com.intellij.execution.ui.actions.BaseViewAction;
-import com.intellij.execution.ui.layout.Grid;
-import com.intellij.execution.ui.layout.Tab;
-import com.intellij.execution.ui.layout.ViewContext;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.ui.content.Content;
-
-public class MoveToTabAction extends BaseViewAction {
-  protected void update(final AnActionEvent e, final ViewContext context, final Content[] content) {
-    if (!context.isMoveToGridActionEnabled() || content.length != 1) {
-      setEnabled(e, false);
-      return;
-    }
-    if (isDetached(context, content[0])) {
-      setEnabled(e, false);
-      return;
-    }
-
-    Grid grid = context.findGridFor(content[0]);
-    if (grid == null) {
-      setEnabled(e, false);
-      return;
-    }
-
-
-    Tab tab = context.getTabFor(grid);
-
-    if (ViewContext.TAB_TOOLBAR_PLACE.equals(e.getPlace())) {
-      setEnabled(e, false);
-    } else {
-      setEnabled(e, tab != null && tab.isDefault());
-    }
-  }
-
-  protected void actionPerformed(final AnActionEvent e, final ViewContext context, final Content[] content) {
-    context.getCellTransform().moveToTab(content[0]);
-  }
-}
\ No newline at end of file
index 282ce022dc1a2413547467067a11ca715401a003..fb2f1293e2a90c347136484eb1eeb587d6f78be7 100644 (file)
@@ -21,6 +21,7 @@ import javax.swing.*;
 abstract class AbstractTab {
 
   int myIndex;
+  int myDefaultIndex = -1;
   String myDisplayName;
   Icon myIcon;
 
@@ -38,6 +39,7 @@ abstract class AbstractTab {
 
   void copyFrom(final AbstractTab from) {
     myIndex = from.myIndex;
+    myDefaultIndex = from.myDefaultIndex;
     myDisplayName = from.myDisplayName;
     myIcon = from.myIcon;
 
diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/DockableGridContainerFactory.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/DockableGridContainerFactory.java
new file mode 100644 (file)
index 0000000..4e9c694
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.execution.ui.layout.impl;
+
+import com.intellij.ui.docking.DockContainer;
+import com.intellij.ui.docking.DockContainerFactory;
+import com.intellij.ui.docking.DockableContent;
+
+/**
+ * @author Dennis.Ushakov
+ */
+public class DockableGridContainerFactory implements DockContainerFactory {
+  public static final String TYPE = "runner-grid";
+
+  @Override
+  public DockContainer createContainer(DockableContent content) {
+    final RunnerContentUi.DockableGrid dockableGrid = (RunnerContentUi.DockableGrid)content;
+    return new RunnerContentUi(dockableGrid.getRunnerUi(), dockableGrid.getOriginalRunnerUi(), dockableGrid.getWindow());
+  }
+
+  @Override
+  public void dispose() {}
+}
index f479bc7860e9b6b40932c5a8d1cc539298ee2157..8a03f1bc543fcfd3b27e61cbee12f28ca9c570ca 100644 (file)
@@ -18,18 +18,16 @@ package com.intellij.execution.ui.layout.impl;
 
 import com.intellij.execution.ui.layout.*;
 import com.intellij.execution.ui.layout.actions.MinimizeViewAction;
-import com.intellij.openapi.Disposable;
 import com.intellij.openapi.actionSystem.ActionGroup;
 import com.intellij.openapi.actionSystem.DataProvider;
-import com.intellij.openapi.ui.popup.ComponentPopupBuilder;
 import com.intellij.openapi.ui.popup.JBPopup;
-import com.intellij.openapi.ui.popup.JBPopupFactory;
-import com.intellij.openapi.util.*;
-import com.intellij.openapi.wm.IdeFrame;
-import com.intellij.openapi.wm.WindowManager;
+import com.intellij.openapi.util.ActionCallback;
+import com.intellij.openapi.util.DimensionService;
+import com.intellij.openapi.util.MutualMap;
 import com.intellij.ui.components.panels.NonOpaquePanel;
-import com.intellij.ui.components.panels.Wrapper;
 import com.intellij.ui.content.Content;
+import com.intellij.ui.docking.DockContainer;
+import com.intellij.ui.docking.DockManager;
 import com.intellij.ui.switcher.SwitchTarget;
 import com.intellij.ui.tabs.JBTabs;
 import com.intellij.ui.tabs.TabInfo;
@@ -43,15 +41,14 @@ import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
-import javax.swing.border.EmptyBorder;
 import java.awt.*;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import java.util.ArrayList;
+import java.util.List;
 import java.util.Set;
 
-public class GridCellImpl implements GridCell, Disposable {
-
+public class GridCellImpl implements GridCell {
   private final GridImpl myContainer;
 
   private final MutualMap<Content, TabInfo> myContents = new MutualMap<Content, TabInfo>(true);
@@ -62,19 +59,25 @@ public class GridCellImpl implements GridCell, Disposable {
   private final PlaceInGrid myPlaceInGrid;
 
   private final ViewContextEx myContext;
-  private CellTransform.Restore.List myRestoreFromDetach;
   private JBPopup myPopup;
-  private boolean myDisposed;
 
   public GridCellImpl(ViewContextEx context, @NotNull GridImpl container, GridImpl.Placeholder placeholder, PlaceInGrid placeInGrid) {
     myContext = context;
     myContainer = container;
 
-    Disposer.register(container, this);
-
     myPlaceInGrid = placeInGrid;
     myPlaceholder = placeholder;
-    myTabs = new JBTabsImpl(myContext.getProject(), myContext.getActionManager(), myContext.getFocusManager(), container).setDataProvider(new DataProvider() {
+    myTabs = new JBTabsImpl(myContext.getProject(), myContext.getActionManager(), myContext.getFocusManager(), container) {
+      @Override
+      protected Color getFocusedTopFillColor() {
+        return new Color(202, 211, 227);
+      }
+
+      @Override
+      protected Color getFocusedBottomFillColor() {
+        return new Color(194, 203, 219);
+      }
+    }.setDataProvider(new DataProvider() {
       @Nullable
       public Object getData(@NonNls final String dataId) {
         if (ViewContext.CONTENT_KEY.is(dataId)) {
@@ -96,24 +99,18 @@ public class GridCellImpl implements GridCell, Disposable {
         return new UiDecoration(null, new Insets(1, -1, 1, -1));
       }
     }).setSideComponentVertical(!context.getLayoutSettings().isToolbarHorizontal())
-      .setStealthTabMode(true)
-      .setFocusCycle(false).setPaintFocus(true).setProvideSwitchTargets(false);
+      .setStealthTabMode(true).setFocusCycle(false).setPaintFocus(true)
+      .setProvideSwitchTargets(false).setTabDraggingEnabled(true);
 
     myTabs.addTabMouseListener(new MouseAdapter() {
       public void mousePressed(final MouseEvent e) {
         if (UIUtil.isCloseClick(e)) {
-          if (isDetached()) {
-            myPopup.cancel();
-            myPopup = null;
-          }
-          else {
             minimize(e);
-          }
         }
       }
     });
     rebuildPopupGroup();
-    myTabs.addListener(new TabsListener() {
+    myTabs.addListener(new TabsListener.Adapter() {
 
       public void beforeSelectionChanged(TabInfo oldSelection, TabInfo newSelection) {
         if (oldSelection != null && myContext.isStateBeingRestored()) {
@@ -181,7 +178,7 @@ public class GridCellImpl implements GridCell, Disposable {
       }
     }
     else {
-      if (myPlaceholder.isNull() && !isDetached()) {
+      if (myPlaceholder.isNull()) {
         myPlaceholder.setContent(myTabs.getComponent());
       }
 
@@ -211,7 +208,7 @@ public class GridCellImpl implements GridCell, Disposable {
 
     ActionGroup group = (ActionGroup)myContext.getActionManager().getAction(RunnerContentUi.VIEW_TOOLBAR);
     tabInfo.setTabLabelActions(group, ViewContext.CELL_TOOLBAR_PLACE);
-
+    tabInfo.setDragOutDelegate(((RunnerContentUi)myContext).myDragOutDelegate);
     return tabInfo;
   }
 
@@ -248,7 +245,7 @@ public class GridCellImpl implements GridCell, Disposable {
     return myMinimizedContents.contains(content);
   }
 
-  public java.util.List<SwitchTarget> getTargets(boolean onlyVisible) {
+  public List<SwitchTarget> getTargets(boolean onlyVisible) {
     if (myTabs.getPresentation().isHideTabs()) return new ArrayList<SwitchTarget>();
 
     return myTabs.getTargets(onlyVisible, false);
@@ -287,7 +284,7 @@ public class GridCellImpl implements GridCell, Disposable {
   }
 
   @Nullable
-  private TabInfo getTabFor(Content content) {
+  TabInfo getTabFor(Content content) {
     return myContents.getValue(content);
   }
 
@@ -306,14 +303,21 @@ public class GridCellImpl implements GridCell, Disposable {
     restoreProportions();
 
     Content[] contents = getContents();
+    int window = 0;
     for (Content each : contents) {
-      if (myContainer.getStateFor(each).isMinimizedInGrid()) {
+      final View view = myContainer.getStateFor(each);
+      if (view.isMinimizedInGrid()) {
         minimize(each);
       }
+      window = view.getWindow();
     }
-
-    if (!isRestoringFromDetach() && myContainer.getTab().isDetached(myPlaceInGrid) && contents.length > 0) {
-      _detach(!myContext.isStateBeingRestored()).notifyWhenDone(result);
+    final Tab tab = myContainer.getTab();
+    final boolean detached = (tab != null && tab.isDetached(myPlaceInGrid)) || window != myContext.getWindow();
+    if (detached && contents.length > 0) {
+      if (tab != null) {
+        tab.setDetached(myPlaceInGrid, false);
+      }
+      myContext.detachTo(window, this).notifyWhenDone(result);
     } else {
       result.setDone();
     }
@@ -321,7 +325,7 @@ public class GridCellImpl implements GridCell, Disposable {
     return result;
   }
 
-  private Content[] getContents() {
+  Content[] getContents() {
     return myContents.getKeys().toArray(new Content[myContents.size()]);
   }
 
@@ -339,6 +343,14 @@ public class GridCellImpl implements GridCell, Disposable {
     for (Content each : myMinimizedContents) {
       saveState(each, true);
     }
+
+    final DimensionService service = DimensionService.getInstance();
+    final Dimension size = myContext.getContentManager().getComponent().getSize();
+    service.setSize(getDimensionKey(), size, myContext.getProject());
+    if (myContext.getWindow() != 0) {
+      final JFrame frame = (JFrame)DockManager.getInstance(myContext.getProject()).getIdeFrame((DockContainer)myContext);
+      service.setLocation(getDimensionKey(), frame.getLocationOnScreen());
+    }
   }
 
   public void saveProportions() {
@@ -350,8 +362,7 @@ public class GridCellImpl implements GridCell, Disposable {
     state.setMinimizedInGrid(minimized);
     state.setPlaceInGrid(myPlaceInGrid);
     state.assignTab(myContainer.getTabIndex());
-
-    state.getTab().setDetached(myPlaceInGrid, isDetached());
+    state.setWindow(myContext.getWindow());
   }
 
   public void restoreProportions() {
@@ -362,7 +373,7 @@ public class GridCellImpl implements GridCell, Disposable {
     for (Content each : myContents.getKeys()) {
       final TabInfo eachTab = getTabFor(each);
       boolean isSelected = eachTab != null && myTabs.getSelectedInfo() == eachTab;
-      if (isSelected && (isShowing || isDetached())) {
+      if (isSelected && isShowing) {
         myContext.getContentManager().addSelectedContent(each);
       }
       else {
@@ -391,147 +402,22 @@ public class GridCellImpl implements GridCell, Disposable {
     }
   }
 
-  public ActionCallback detach() {
-    return _detach(true);
-  }
-
-  private ActionCallback _detach(final boolean requestFocus) {
-    myContext.saveUiState();
-
-    final DimensionService dimService = DimensionService.getInstance();
-    Point storedLocation = dimService.getLocation(getDimensionKey(), myContext.getProject());
-    Dimension storedSize = dimService.getSize(getDimensionKey(), myContext.getProject());
-
-    final IdeFrame frame = WindowManager.getInstance().getIdeFrame(myContext.getProject());
-    final Rectangle targetBounds = frame.suggestChildFrameBounds();
-
-
-    if (storedLocation != null && storedSize != null) {
-      targetBounds.setLocation(storedLocation);
-      targetBounds.setSize(storedSize);
-    }
-
-    final ActionCallback result = new ActionCallback();
-
-    if (storedLocation == null || storedSize == null) {
-      if (myContents.size() > 0) {
-        myContext.validate(myContents.getKeys().iterator().next(), new ActiveRunnable() {
-          public ActionCallback run() {
-            if (!myTabs.getComponent().isShowing()) {
-              detachTo(targetBounds.getLocation(), targetBounds.getSize(), false, requestFocus).notifyWhenDone(result);
-            } else {
-              detachForShowingTabs(requestFocus).notifyWhenDone(result);
-            }
-
-            return new ActionCallback.Done();
-          }
-        });
-
-        return result;
-      }
-    }
-
-    detachTo(targetBounds.getLocation(), targetBounds.getSize(), false, requestFocus).notifyWhenDone(result);
-
-    return result;
-  }
-
-  private ActionCallback detachForShowingTabs(boolean requestFocus) {
-    return detachTo(myTabs.getComponent().getLocationOnScreen(), myTabs.getComponent().getSize(), false, requestFocus);
-  }
-
-  private ActionCallback detachTo(Point screenPoint, Dimension size, boolean dragging, final boolean requestFocus) {
-    if (isDetached()) {
-      if (myPopup != null) {
-        return new ActionCallback.Done();
-      }
-    }
-
-    final Content[] contents = getContents();
-
-    myRestoreFromDetach = new CellTransform.Restore.List();
-
-    myRestoreFromDetach.add(myPlaceholder.detach());
-    myRestoreFromDetach.add(myContainer.detach(contents));
-    myRestoreFromDetach.add(new CellTransform.Restore() {
-      public ActionCallback restoreInGrid() {
-        ensureVisible();
-        return new ActionCallback.Done();
-      }
-    });
-
-    myPopup = createPopup(dragging, requestFocus);
-    myPopup.setSize(size);
-    myPopup.setLocation(screenPoint);
-    myPopup.show(myContext.getContentManager().getComponent());
-
-    myContext.saveUiState();
-
-    myTabs.updateTabActions(true);
-
-    return new ActionCallback.Done();
-  }
-
-  private void ensureVisible() {
-    if (myTabs.getSelectedInfo() != null) {
-      myContext.select(getContentFor(myTabs.getSelectedInfo()), true);
-    }
-  }
-
-  private JBPopup createPopup(boolean dragging, final boolean requestFocus) {
-    Wrapper wrapper = new Wrapper(myTabs.getComponent());
-    wrapper.setBorder(new EmptyBorder(1, 0, 0, 0));
-    final ComponentPopupBuilder builder = JBPopupFactory.getInstance().createComponentPopupBuilder(wrapper, myTabs.getComponent())
-      .setTitle(myContainer.getSessionName())
-      .setMovable(true)
-      .setRequestFocus(requestFocus)
-      .setFocusable(true)
-      .setResizable(true)
-      .setDimensionServiceKey(myContext.getProject(), getDimensionKey(), true)
-      .setCancelOnOtherWindowOpen(false)
-      .setCancelOnClickOutside(false)
-      .setCancelKeyEnabled(true)
-      .setLocateByContent(dragging)
-      .setLocateWithinScreenBounds(!dragging)
-      .setCancelKeyEnabled(false)
-      .setBelongsToGlobalPopupStack(false)
-      .setModalContext(false)
-      .setCancelCallback(new Computable<Boolean>() {
-        public Boolean compute() {
-          if (myDisposed || myContents.size() == 0) return Boolean.TRUE;
-          myRestoreFromDetach.restoreInGrid();
-          myRestoreFromDetach = null;
-          myContext.saveUiState();
-          myTabs.updateTabActions(true);
-          return Boolean.TRUE;
-        }
-      });
-
-    return builder.createPopup();
-  }
-
-  public void attach() {
-    if (isDetached()) {
-      myPopup.cancel();
-      myPopup = null;
-    }
-  }
-
-
-  public boolean isDetached() {
-    return myRestoreFromDetach != null && !myRestoreFromDetach.isRestoringNow();
+  @Nullable
+  public Point getLocation() {
+    return DimensionService.getInstance().getLocation(getDimensionKey(), myContext.getProject());
   }
 
-  public boolean isRestoringFromDetach() {
-    return myRestoreFromDetach != null && myRestoreFromDetach.isRestoringNow();
+  @Nullable
+  public Dimension getSize() {
+    return DimensionService.getInstance().getSize(getDimensionKey(), myContext.getProject());
   }
-
+  
   private String getDimensionKey() {
     return "GridCell.Tab." + myContainer.getTab().getIndex() + "." + myPlaceInGrid.name();
   }
 
-  public boolean isValidForCalculatePropertions() {
-    return !isDetached() && getContentCount() > 0;
+  public boolean isValidForCalculateProportions() {
+    return getContentCount() > 0;
   }
 
   public void minimize(Content content) {
@@ -553,13 +439,4 @@ public class GridCellImpl implements GridCell, Disposable {
     updateSelection(myTabs.getComponent().getRootPane() != null);
     return new ActionCallback.Done();
   }
-
-  public void dispose() {
-    myDisposed = true;
-
-    if (myPopup != null) {
-      myPopup.cancel();
-      myPopup = null;
-    }
-  }
 }
index dfb6659f6c1aced2a8a77c668b014e32e2e7b86b..f023d86d3a9b29a542380e1f59f4b09cd59f96e2 100644 (file)
@@ -35,7 +35,7 @@ import java.awt.*;
 import java.util.*;
 import java.util.List;
 
-public class GridImpl extends Wrapper implements Grid, Disposable, CellTransform.Facade, DataProvider {
+public class GridImpl extends Wrapper implements Grid, Disposable, DataProvider {
   private final ThreeComponentsSplitter myTopSplit = new ThreeComponentsSplitter();
   private final Splitter mySplitter = new Splitter(true);
 
@@ -152,8 +152,7 @@ public class GridImpl extends Wrapper implements Grid, Disposable, CellTransform
 
   public boolean updateGridUI() {
     for (final GridCellImpl cell : myPlaceInGrid2Cell.values()) {
-      final boolean eachToHide = myContents.size() == 1 && !cell.isDetached();
-      cell.setHideTabs(eachToHide);
+      cell.setHideTabs(myContents.size() == 1);
     }
 
     final Content onlyContent = myContents.get(0);
@@ -252,7 +251,7 @@ public class GridImpl extends Wrapper implements Grid, Disposable, CellTransform
 
     final GridCellImpl cell = myPlaceInGrid2Cell.get(placeInGrid);
 
-    if (!cell.isValidForCalculatePropertions()) return;
+    if (!cell.isValidForCalculateProportions()) return;
 
     final TabImpl tab = (TabImpl)getTab();
 
@@ -335,19 +334,12 @@ public class GridImpl extends Wrapper implements Grid, Disposable, CellTransform
     ArrayList<Content> result = new ArrayList<Content>();
 
     for (Content each : getContents()) {
-      if (!isDetached(each)) {
-        result.add(each);
-      }
+      result.add(each);
     }
 
     return result;
   }
 
-
-  public boolean isDetached(Content content) {
-    return getCellFor(content).isDetached();
-  }
-
   public List<Content> getContents() {
     return myContents;
   }
@@ -360,28 +352,6 @@ public class GridImpl extends Wrapper implements Grid, Disposable, CellTransform
     });
   }
 
-  public void moveToTab(final Content content) {
-    myViewContext.getCellTransform().moveToTab(content);
-  }
-
-  public void moveToGrid(final Content content) {
-    myViewContext.getCellTransform().moveToGrid(content);
-  }
-
-  public CellTransform.Restore detach(final Content[] content) {
-    final CellTransform.Restore.List restore = new CellTransform.Restore.List();
-    restore.add(myViewContext.getCellTransform().detach(content));
-    restore.add(new CellTransform.Restore() {
-      public ActionCallback restoreInGrid() {
-        revalidate();
-        repaint();
-        return new ActionCallback.Done();
-      }
-    });
-
-    return restore;
-  }
-
   @Nullable
   public Object getData(@NonNls final String dataId) {
     if (ViewContext.CONTEXT_KEY.is(dataId)) {
@@ -394,10 +364,6 @@ public class GridImpl extends Wrapper implements Grid, Disposable, CellTransform
     return null;
   }
 
-  public String getSessionName() {
-    return mySessionName;
-  }
-
   @Nullable
   public SwitchTarget getCellFor(Component c) {
     Component eachParent = c;
@@ -419,9 +385,7 @@ public class GridImpl extends Wrapper implements Grid, Disposable, CellTransform
     Collection<GridCellImpl> cells = myPlaceInGrid2Cell.values();
     ArrayList<SwitchTarget> result = new ArrayList<SwitchTarget>();
     for (GridCellImpl each : cells) {
-      if (!each.isDetached()) {
-        result.addAll(each.getTargets(onlyVisible));
-      }
+      result.addAll(each.getTargets(onlyVisible));
     }
     return result;
   }
diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/JBRunnerTabs.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/impl/JBRunnerTabs.java
new file mode 100644 (file)
index 0000000..0873fe9
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.execution.ui.layout.impl;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.actionSystem.ActionGroup;
+import com.intellij.openapi.actionSystem.ActionManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.wm.IdeFocusManager;
+import com.intellij.ui.Gray;
+import com.intellij.ui.awt.RelativePoint;
+import com.intellij.ui.tabs.TabInfo;
+import com.intellij.ui.tabs.TabsUtil;
+import com.intellij.ui.tabs.UiDecorator;
+import com.intellij.ui.tabs.impl.JBTabsImpl;
+import com.intellij.ui.tabs.impl.TabLabel;
+import com.intellij.util.ui.SameColor;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import java.awt.*;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Dennis.Ushakov
+ */
+public class
+  JBRunnerTabs extends JBTabsImpl {
+  public JBRunnerTabs(@Nullable Project project, ActionManager actionManager, IdeFocusManager focusManager, @NotNull Disposable parent) {
+    super(project, actionManager, focusManager, parent);
+  }
+
+  @Override
+  protected void paintFirstGhost(Graphics2D g2d) {}
+
+  @Override
+  protected void paintLastGhost(Graphics2D g2d) {}
+
+  public boolean isGhostsAlwaysVisible() {
+    return false;
+  }
+
+  protected void doPaintInactive(Graphics2D g2d,
+                                 boolean leftGhostExists,
+                                 TabLabel label,
+                                 Rectangle effectiveBounds,
+                                 boolean rightGhostExists) {
+    Insets insets = getTabsBorder().getEffectiveBorder();
+
+    int _x = effectiveBounds.x + insets.left;
+    int _y = effectiveBounds.y + insets.top + 3;
+    int _width = effectiveBounds.width - insets.left - insets.right;
+    int _height = effectiveBounds.height - insets.top - insets.bottom - 3;
+    _height -= TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT;
+
+    g2d
+      .setPaint(new GradientPaint(_x, _y, new Color(255, 255, 255, 180), _x, _y + effectiveBounds.height, new Color(255, 255, 255, 100)));
+    g2d.fillRect(_x, _y, _width, _height);
+
+    g2d.setColor(new Color(255, 255, 255, 100));
+    g2d.drawRect(_x, _y, _width - 1, _height - 1);
+  }
+
+  @Override
+  protected void doPaintBackground(Graphics2D g2d, Rectangle clip) {
+    g2d.setColor(UIUtil.getPanelBackground());
+    g2d.fill(clip);
+
+    g2d.setColor(new Color(0, 0, 0, 50));
+    g2d.fill(clip);
+
+    List<TabInfo> visibleInfos = getVisibleInfos();
+
+    Insets insets = getTabsBorder().getEffectiveBorder();
+
+    int maxOffset = 0;
+    int maxLength = 0;
+
+    for (int i = visibleInfos.size() - 1; i >= 0; i--) {
+      TabInfo visibleInfo = visibleInfos.get(i);
+      TabLabel tabLabel = myInfo2Label.get(visibleInfo);
+      Rectangle r = tabLabel.getBounds();
+      if (r.width == 0 || r.height == 0) continue;
+      maxOffset = r.x + r.width;
+      maxLength = r.height;
+      break;
+    }
+
+    maxOffset++;
+
+    Rectangle r2 = getBounds();
+
+    Rectangle rectangle;
+    int y = r2.y + insets.top;
+    int height = maxLength - insets.top - insets.bottom;
+    height -= TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT;
+
+    rectangle = new Rectangle(maxOffset, y, r2.width - maxOffset - insets.left - insets.right, height);
+
+    g2d.setPaint(UIUtil.getPanelBackground());
+    g2d.fillRect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
+    g2d.fillRect(0, 0, rectangle.x + rectangle.width, 3);
+    g2d.fillRect(2, maxLength, getSize().width, getSize().height);
+    g2d.drawLine(0, 0, 0, getSize().height);
+  }
+
+  protected void paintSelectionAndBorder(Graphics2D g2d) {
+    if (getSelectedInfo() == null) return;
+
+    TabLabel label = getSelectedLabel();
+    Rectangle r = label.getBounds();
+    r = new Rectangle(r.x, r.y + 3, r.width, r.height - 3);
+
+    ShapeInfo selectedShape = _computeSelectedLabelShape(r);
+
+    Insets insets = getTabsBorder().getEffectiveBorder();
+    Insets i = selectedShape.path.transformInsets(insets);
+
+    int _x = r.x;
+    int _y = r.y;
+    int _height = r.height;
+
+    if (!isHideTabs()) {
+      g2d.setPaint(new GradientPaint(_x, _y, new SameColor(255), _x, _y + _height - 3, UIUtil.getPanelBackground()));
+
+      g2d.fill(selectedShape.fillPath.getShape());
+
+      g2d.setColor(new Color(255, 255, 255, 180));
+      g2d.draw(selectedShape.fillPath.getShape());
+
+      // fix right side due to swing stupidity (fill & draw will occupy different shapes)
+      g2d.draw(selectedShape.labelPath
+                 .transformLine(selectedShape.labelPath.getMaxX() - selectedShape.labelPath.deltaX(1), selectedShape.labelPath.getY() +
+                                                                                                       selectedShape.labelPath.deltaY(1),
+                                selectedShape.labelPath.getMaxX() - selectedShape.labelPath.deltaX(1), selectedShape.labelPath.getMaxY() -
+                                                                                                       selectedShape.labelPath.deltaY(4)));
+    }
+    g2d.setColor(UIUtil.getPanelBackground());
+    g2d.fillRect(2, selectedShape.labelPath.getMaxY() - 2, selectedShape.path.getMaxX() - 2, 3);
+    g2d.drawLine(1, selectedShape.labelPath.getMaxY(), 1, getHeight() - 1);
+    g2d.drawLine(selectedShape.path.getMaxX() - 1, selectedShape.labelPath.getMaxY() - 4,
+                 selectedShape.path.getMaxX() - 1, getHeight() - 1);
+
+    if (isHideTabs()) return;
+    g2d.setColor(new Color(0, 0, 0, 50));
+    g2d.drawLine(1, selectedShape.labelPath.getMaxY(), 1, getHeight() - 1);
+    g2d.drawLine(selectedShape.path.getMaxX() - 1, selectedShape.labelPath.getMaxY() - 4,
+                 selectedShape.path.getMaxX() - 1, getHeight() - 1);
+  }
+
+  @Override
+  public Color getBackground() {
+    return Gray._142;
+  }
+
+  protected ShapeInfo _computeSelectedLabelShape(Rectangle r) {
+    final ShapeInfo shape = new ShapeInfo();
+
+    shape.path = getEffectiveLayout().createShapeTransform(getSize());
+    shape.insets = shape.path.transformInsets(getLayoutInsets());
+    shape.labelPath = shape.path.createTransform(r);
+
+    shape.labelBottomY = shape.labelPath.getMaxY() - shape.labelPath.deltaY(TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT - 1);
+    shape.labelTopY = shape.labelPath.getY() + shape.labelPath.deltaY(1);
+    shape.labelLeftX = shape.labelPath.getX();
+    shape.labelRightX = shape.labelPath.getMaxX() - shape.labelPath.deltaX(1);
+
+    int leftX = shape.insets.left;
+
+    shape.path.moveTo(leftX, shape.labelBottomY);
+    shape.path.lineTo(shape.labelLeftX, shape.labelBottomY);
+    shape.path.lineTo(shape.labelLeftX, shape.labelTopY);
+    shape.path.lineTo(shape.labelRightX, shape.labelTopY);
+    shape.path.lineTo(shape.labelRightX, shape.labelBottomY);
+
+    int lastX = shape.path.getWidth() - shape.path.deltaX(shape.insets.right);
+
+    shape.path.lineTo(lastX, shape.labelBottomY);
+    shape.path.lineTo(lastX, shape.labelBottomY + shape.labelPath.deltaY(TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT - 1));
+    shape.path.lineTo(leftX, shape.labelBottomY + shape.labelPath.deltaY(TabsUtil.ACTIVE_TAB_UNDERLINE_HEIGHT - 1));
+
+    shape.path.closePath();
+    shape.fillPath = shape.path.copy();
+
+    return shape;
+  }
+
+  @Override
+  public int getToolbarInset() {
+    return 8;
+  }
+
+  public boolean shouldAddToGlobal(Point point) {
+    final TabLabel label = getSelectedLabel();
+    if (label == null || point == null) {
+      return true;
+    }
+    final Rectangle bounds = label.getBounds();
+    return point.y <= bounds.y + bounds.height;
+  }
+
+  @Override
+  public Rectangle layout(JComponent c, Rectangle bounds) {
+    if (c instanceof Toolbar) {
+      bounds.height -= 5;
+      return super.layout(c, bounds);
+    }
+    if (c instanceof GridImpl) {
+      bounds.x -= 1;
+      bounds.width += 1;
+      if (!isHideTabs()) {
+        bounds.y -= 1;
+        bounds.height += 1;
+      }
+    }
+    return super.layout(c, bounds);
+  }
+
+  @Override
+  public void processDropOver(TabInfo over, RelativePoint relativePoint) {
+    super.processDropOver(over, relativePoint);
+    final Point point = relativePoint.getPoint(getComponent());
+    for (Map.Entry<TabInfo, TabLabel> entry : myInfo2Label.entrySet()) {
+      final TabLabel label = entry.getValue();
+      if (label.getBounds().contains(point) && myDropInfo != entry.getKey()) {
+        select(entry.getKey(), false);
+        break;
+      }
+    }
+  }
+
+  @Override
+  protected TabLabel createTabLabel(TabInfo info) {
+    return new MyTabLabel(this, info);
+  }
+
+  private static class MyTabLabel extends TabLabel {
+    public MyTabLabel(JBTabsImpl tabs, final TabInfo info) {
+      super(tabs, info);
+    }
+
+    @Override
+    public void apply(UiDecorator.UiDecoration decoration) {
+      setFont(UIUtil.getLabelFont(UIUtil.FontSize.SMALL));
+      myLabel.setFont(UIUtil.getLabelFont(UIUtil.FontSize.SMALL));
+      setBorder(new EmptyBorder(5, 5, 7, 5));
+    }
+
+    @Override
+    public void setTabActionsAutoHide(boolean autoHide) {
+      super.setTabActionsAutoHide(autoHide);
+      apply(null);
+    }
+
+    @Override
+    public void setTabActions(ActionGroup group) {
+      super.setTabActions(group);
+      if (myActionPanel != null) {
+        final JComponent wrapper = (JComponent)myActionPanel.getComponent(0);
+        wrapper.remove(0);
+        wrapper.add(Box.createHorizontalStrut(6), BorderLayout.WEST);
+      }
+    }
+
+    @Override
+    protected int getSelectedOffset() {
+      return getNonSelectedOffset();
+    }
+  }
+}
index b2732529f4f69e8a1c5247c147acb940adc80346..42c2d7c48830146061ed720e47b8dc073653b1ac 100644 (file)
@@ -28,21 +28,28 @@ import com.intellij.openapi.util.ActiveRunnable;
 import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.util.Ref;
 import com.intellij.openapi.wm.IdeFocusManager;
+import com.intellij.openapi.wm.IdeFrame;
 import com.intellij.openapi.wm.ToolWindow;
 import com.intellij.ui.UIBundle;
+import com.intellij.ui.awt.RelativePoint;
+import com.intellij.ui.awt.RelativeRectangle;
 import com.intellij.ui.components.panels.NonOpaquePanel;
 import com.intellij.ui.components.panels.Wrapper;
 import com.intellij.ui.content.*;
+import com.intellij.ui.docking.DockContainer;
+import com.intellij.ui.docking.DockManager;
+import com.intellij.ui.docking.DockableContent;
+import com.intellij.ui.docking.DragSession;
+import com.intellij.ui.docking.impl.DockManagerImpl;
 import com.intellij.ui.switcher.QuickActionProvider;
 import com.intellij.ui.switcher.SwitchProvider;
 import com.intellij.ui.switcher.SwitchTarget;
 import com.intellij.ui.tabs.JBTabs;
 import com.intellij.ui.tabs.TabInfo;
 import com.intellij.ui.tabs.TabsListener;
-import com.intellij.ui.tabs.UiDecorator;
-import com.intellij.ui.tabs.impl.JBTabsImpl;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.ui.AbstractLayoutManager;
+import com.intellij.util.ui.UIUtil;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -50,13 +57,15 @@ import org.jetbrains.annotations.Nullable;
 import javax.swing.*;
 import javax.swing.border.EmptyBorder;
 import java.awt.*;
+import java.awt.event.MouseEvent;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.util.*;
 import java.util.List;
+import java.util.concurrent.CopyOnWriteArraySet;
 
 public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Facade, ViewContextEx, PropertyChangeListener, SwitchProvider,
-                                        QuickActionProvider {
+                                        QuickActionProvider, DockContainer {
 
   @NonNls public static final String LAYOUT = "Runner.Layout";
   @NonNls public static final String VIEW_POPUP = "Runner.View.Popup";
@@ -70,8 +79,9 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
   MyComponent myComponent = new MyComponent();
 
   private final Wrapper myToolbar = new Wrapper();
+  final MyDragOutDelegate myDragOutDelegate = new MyDragOutDelegate();
 
-  JBTabs myTabs;
+  JBRunnerTabs myTabs;
   private final Comparator<TabInfo> myTabsComparator = new Comparator<TabInfo>() {
     public int compare(final TabInfo o1, final TabInfo o2) {
       //noinspection ConstantConditions
@@ -110,6 +120,20 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
   private int myAttractionCount;
   private ActionGroup myLeftToolbarActions;
 
+  private JBTabs myCurrentOver;
+  private Image myCurrentOverImg;
+  private TabInfo myCurrentOverInfo;
+  private RunnerContentUi myOriginal;
+  private CopyOnWriteArraySet<Listener> myDockingListeners = new CopyOnWriteArraySet<Listener>();
+  private Set<RunnerContentUi> myChildren = new TreeSet<RunnerContentUi>(new Comparator<RunnerContentUi>() {
+    @Override
+    public int compare(RunnerContentUi o1, RunnerContentUi o2) {
+      return o1.myWindow - o2.myWindow;
+    }
+  }); 
+  private int myWindow;
+  private boolean myDisposing;
+
   public RunnerContentUi(Project project,
                          RunnerLayoutUi ui,
                          ActionManager actionManager,
@@ -124,6 +148,12 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
     myFocusManager = focusManager;
   }
 
+  public RunnerContentUi(RunnerContentUi ui, RunnerContentUi original, int window) {
+    this(ui.myProject, ui.myRunnerUi, ui.myActionManager, ui.myFocusManager, ui.myLayoutSettings, ui.mySessionName);
+    myOriginal = original;
+    original.myChildren.add(this);
+    myWindow = window == 0 ? original.findFreeWindow() : window;
+  }
 
   public void setTopActions(@NotNull final ActionGroup topActions, @NotNull String place) {
     myTopActions = topActions;
@@ -150,32 +180,27 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
   public void initUi() {
     if (myTabs != null) return;
 
-    myTabs = new JBTabsImpl(myProject, myActionManager, myFocusManager, this)
-      .setDataProvider(new DataProvider() {
-        public Object getData(@NonNls final String dataId) {
-          if (ViewContext.CONTENT_KEY.is(dataId)) {
-            TabInfo info = myTabs.getTargetInfo();
-            if (info != null) {
-              return getGridFor(info).getData(dataId);
-            }
+    myTabs = (JBRunnerTabs)new JBRunnerTabs(myProject, myActionManager, myFocusManager, this).setDataProvider(new DataProvider() {
+      public Object getData(@NonNls final String dataId) {
+        if (ViewContext.CONTENT_KEY.is(dataId)) {
+          TabInfo info = myTabs.getTargetInfo();
+          if (info != null) {
+            return getGridFor(info).getData(dataId);
           }
-          else if (ViewContext.CONTEXT_KEY.is(dataId)) {
-            return RunnerContentUi.this;
-          }
-          return null;
         }
-      }).setProvideSwitchTargets(false).setInnerInsets(new Insets(1, 0, 0, 0)).setToDrawBorderIfTabsHidden(false)
-      .setUiDecorator(new UiDecorator() {
-        @NotNull
-        public UiDecoration getDecoration() {
-          return new UiDecoration(null, new Insets(1, 8, 1, 8));
+        else if (ViewContext.CONTEXT_KEY.is(dataId)) {
+          return RunnerContentUi.this;
         }
-      }).getJBTabs();
+        return null;
+      }
+    }).setTabLabelActionsAutoHide(false).setProvideSwitchTargets(false).setInnerInsets(new Insets(0, 0, 0, 0))
+      .setToDrawBorderIfTabsHidden(false).setTabDraggingEnabled(isMoveToGridActionEnabled()).setUiDecorator(null).getJBTabs();
     rebuildTabPopup();
 
-
-    myTabs.getPresentation().setPaintBorder(0, 0, 0, 0).setTabSidePaintBorder(2).setPaintFocus(false)
+    myTabs.getPresentation().setPaintBorder(0, 0, 0, 0).setPaintFocus(false)
       .setRequestFocusOnLastFocusedComponent(true);
+    myTabs.getComponent().setBackground(myToolbar.getBackground());
+    myTabs.getComponent().setBorder(new EmptyBorder(0, 2, 0, 0));
 
     final NonOpaquePanel wrappper = new NonOpaquePanel(new BorderLayout(0, 0));
     wrappper.add(myToolbar, BorderLayout.WEST);
@@ -194,6 +219,11 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
         }
       }
 
+      @Override
+      public void tabsMoved() {
+        saveUiState();
+      }
+
       public void selectionChanged(final TabInfo oldSelection, final TabInfo newSelection) {
         if (!myTabs.getComponent().isShowing()) return;
 
@@ -207,6 +237,14 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
         }
       }
     });
+
+    if (myOriginal != null) {
+      final ContentManager manager = ContentFactory.SERVICE.getInstance().createContentManager(this, false, myProject);
+      Disposer.register((Disposable)myRunnerUi, manager);
+      manager.getComponent();
+    } else {
+      DockManager.getInstance(myProject).register(this);
+    }
   }
 
   private void rebuildTabPopup() {
@@ -249,10 +287,15 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
     return group;
   }
 
-  public void doWhenInitialized(final Runnable runnable) {
-    myInitialized.doWhenDone(runnable);
+  @Override
+  public boolean isOriginal() {
+    return myOriginal == null;
   }
 
+  @Override
+  public int getWindow() {
+    return myWindow;
+  }
 
   public void propertyChange(final PropertyChangeEvent evt) {
     Content content = (Content)evt.getSource();
@@ -302,11 +345,193 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
     }
   }
 
+  @Override
+  public ActionCallback detachTo(int window, GridCell cell) {
+    if (myOriginal != null) {
+      return myOriginal.detachTo(window, cell);
+    }
+    RunnerContentUi target = null;
+    if (window > 0) {
+      for (RunnerContentUi child : myChildren) {
+        if (child.myWindow == window) {
+          target = child;
+          break;
+        }
+      }
+    }
+    final GridCellImpl gridCell = (GridCellImpl)cell;
+    final Content[] contents = gridCell.getContents();
+    storeDefaultIndices(contents);
+    for (Content content : contents) {
+      content.putUserData(RunnerLayout.DROP_INDEX, getStateFor(content).getTab().getIndex());
+    }
+    Dimension size = gridCell.getSize();
+    if (size == null) {
+      size = new Dimension(200, 200);
+    }
+    final DockableGrid content = new DockableGrid(null, null, size, Arrays.asList(contents), window);
+    if (target != null) {
+      target.add(content, null);
+    } else {
+      final Point location = gridCell.getLocation();
+      location.translate(size.width / 2, size.height / 2);
+      getDockManager().createNewDockContainerFor(content, new RelativePoint(location));
+    }
+    return new ActionCallback.Done();
+  }
+
+  private void storeDefaultIndices(Content[] contents) {
+    for (Content content : contents) {
+      content.putUserData(RunnerLayout.DEFAULT_INDEX, getStateFor(content).getTab().getDefaultIndex());
+    }
+  }
+
+  @Override
+  public RelativeRectangle getAcceptArea() {
+    return new RelativeRectangle(myTabs.getComponent());
+  }
+
+  @Override
+  public boolean canAccept(DockableContent content, RelativePoint point) {
+    if (!(content instanceof DockableGrid)) {
+      return false;
+    }
+    final RunnerContentUi ui = ((DockableGrid)content).getOriginalRunnerUi();
+    return ui.getProject() == myProject && ui.mySessionName.equals(mySessionName);
+  }
+
+  @Override
   public JComponent getComponent() {
     initUi();
     return myComponent;
   }
 
+  @Override
+  public JComponent getContainerComponent() {
+    initUi();
+    return myManager.getComponent();
+  }
+
+  @Override
+  public void add(DockableContent dockable, RelativePoint dropTarget) {
+    saveUiState();
+
+    final DockableGrid dockableGrid = (DockableGrid)dockable;
+    final List<Content> contents = dockableGrid.getContents();
+    final boolean wasRestoring = myOriginal != null && myOriginal.isStateBeingRestored();
+    setStateIsBeingRestored(true, this);
+    try {
+      final Point point = dropTarget != null ? dropTarget.getPoint(myComponent) : null;
+      boolean hadGrid = !myTabs.shouldAddToGlobal(point);
+
+      for (Content content : contents) {
+        dockableGrid.getRunnerUi().myManager.removeContent(content, false);
+        myManager.removeContent(content, false);
+        if (hadGrid && contents.size() == 1 && !wasRestoring) {
+          getStateFor(content).assignTab(getTabFor(getSelectedGrid()));
+          getStateFor(content).setPlaceInGrid(myLayoutSettings.getDefaultGridPlace(content));
+        } else if (contents.size() == 1 && !wasRestoring) {
+          getStateFor(content).assignTab(myLayoutSettings.createNewTab());
+          getStateFor(content).setPlaceInGrid(myLayoutSettings.getDefaultGridPlace(content));
+        }
+        getStateFor(content).setWindow(myWindow);
+        myManager.addContent(content);
+      }
+    } finally {
+      setStateIsBeingRestored(false, this);
+    }
+
+    saveUiState();
+
+    updateTabsUI(true);
+  }
+
+  @Override
+  public void closeAll() {
+    final Content[] contents = myManager.getContents();
+    for (Content content : contents) {
+      getStateFor(content).setWindow(0);
+    }
+    myManager.removeAllContents(false);
+    for (Content content : contents) {
+      myOriginal.myManager.addContent(content);
+      myOriginal.findCellFor(content).minimize(content);
+    }
+  }
+
+  @Override
+  public void addListener(final Listener listener, Disposable parent) {
+    myDockingListeners.add(listener);
+    Disposer.register(parent, new Disposable() {
+      @Override
+      public void dispose() {
+        myDockingListeners.remove(listener);
+      }
+    });
+  }
+
+  @Override
+  public boolean isEmpty() {
+    return myTabs.isEmptyVisible() || myDisposing;
+  }
+
+  @Override
+  public Image startDropOver(DockableContent content, RelativePoint point) {
+    return null;
+  }
+
+  @Override
+  public Image processDropOver(DockableContent content, RelativePoint point) {
+    JBTabs current = getTabsAt(content, point);
+
+    if (myCurrentOver != null && myCurrentOver != current) {
+      resetDropOver(content);
+    }
+
+    if (myCurrentOver == null && current != null) {
+      myCurrentOver = current;
+      Presentation presentation = content.getPresentation();
+      myCurrentOverInfo = new TabInfo(new JLabel("")).setText(presentation.getText()).setIcon(presentation.getIcon());
+      myCurrentOverImg = myCurrentOver.startDropOver(myCurrentOverInfo, point);
+    }
+
+    if (myCurrentOver != null) {
+      myCurrentOver.processDropOver(myCurrentOverInfo, point);
+    }
+
+    return myCurrentOverImg;
+  }
+
+  @Nullable
+  private JBTabs getTabsAt(DockableContent content, RelativePoint point) {
+    if (content instanceof DockableGrid) {
+      final Point p = point.getPoint(getComponent());
+      Component c = SwingUtilities.getDeepestComponentAt(getComponent(), p.x, p.y);
+      while (c != null) {
+        if (c instanceof JBTabs) {
+          return (JBTabs)c;
+        }
+        c = c.getParent();
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public void resetDropOver(DockableContent content) {
+    if (myCurrentOver != null) {
+      myCurrentOver.resetDropOver(myCurrentOverInfo);
+      myCurrentOver = null;
+      myCurrentOverInfo = null;
+      myCurrentOverImg = null;
+    }
+  }
+
+  @Override
+  public boolean isDisposeWhenEmpty() {
+    return myOriginal != null;
+  }
+
   public boolean isCycleRoot() {
     return false;
   }
@@ -337,6 +562,7 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
 
 
         event.getContent().addPropertyChangeListener(RunnerContentUi.this);
+        fireContentOpened(event.getContent());
       }
 
       public void contentRemoved(final ContentManagerEvent event) {
@@ -349,6 +575,7 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
           removeGridIfNeeded(grid);
         }
         updateTabsUI(false);
+        fireContentClosed(event.getContent());
       }
 
       public void contentRemoveQuery(final ContentManagerEvent event) {
@@ -385,8 +612,17 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
     if (grid != null || !createIfMissing) return grid;
 
     grid = new GridImpl(this, mySessionName);
-    grid.setBorder(new EmptyBorder(1, 0, 0, 0));
 
+    if (myCurrentOver != null || myOriginal != null) {
+      Integer forcedDropIndex = content.getUserData(RunnerLayout.DROP_INDEX);
+      final int index = myTabs.getDropInfoIndex() + (myOriginal != null ? myOriginal.getTabOffsetFor(this) : 0);
+      final TabImpl tab = myLayoutSettings.getOrCreateTab(-1);
+      final Integer defaultIndex = content.getUserData(RunnerLayout.DEFAULT_INDEX);
+      tab.setDefaultIndex(defaultIndex != null ? defaultIndex : -1);
+      tab.setIndex(forcedDropIndex != null ? forcedDropIndex : index);
+      getStateFor(content).assignTab(tab);
+    }
+    
     TabInfo tab = new TabInfo(grid).setObject(getStateFor(content).getTab()).setText("Tab");
 
 
@@ -418,6 +654,15 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
     return grid;
   }
 
+  private int getTabOffsetFor(RunnerContentUi ui) {
+    int offset = myTabs.getTabCount();
+    for (RunnerContentUi child : myChildren) {
+      if (child == ui) break;
+      offset += child.myTabs.getTabCount();
+    }
+    return offset;
+  }
+
   @Nullable
   public GridCell findCellFor(final Content content) {
     GridImpl cell = getGridFor(content, false);
@@ -498,9 +743,11 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
     for (TabInfo each : tabs) {
       hasToolbarContent |= updateTabUI(each);
     }
-
-    myTabs.getPresentation().setHideTabs(!hasToolbarContent && tabs.size() <= 1);
-
+    int tabsCount = tabs.size();
+    for (RunnerContentUi child : myChildren) {
+      tabsCount += child.myTabs.getTabCount();
+    }
+    myTabs.getPresentation().setHideTabs(!hasToolbarContent && tabsCount <= 1 && myOriginal == null);
     myTabs.updateTabActions(validateNow);
 
     if (validateNow) {
@@ -508,7 +755,7 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
     }
   }
 
-  private static boolean updateTabUI(TabInfo tab) {
+  private boolean updateTabUI(TabInfo tab) {
     TabImpl t = getTabFor(tab);
     if (t == null) {
       return false;
@@ -534,9 +781,11 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
     }
 
     if (icon == null && contents.size() == 1) {
+      tab.setHidden(grid.isMinimized(contents.get(0)));
       icon = contents.get(0).getIcon();
     }
 
+    tab.setDragOutDelegate(myTabs.getTabs().size() > 1 || !isOriginal() ? myDragOutDelegate : null);
 
     Tab gridTab = grid.getTab();
     tab.setText(title).setIcon(gridTab != null && gridTab.isDefault() ? null : icon);
@@ -569,10 +818,38 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
   public void saveUiState() {
     if (isStateBeingRestored()) return;
 
+    if (myOriginal != null) {
+      myOriginal.saveUiState();
+      return;
+    }
+    int offset = updateTabsIndices(myTabs, 0);
+    for (RunnerContentUi child : myChildren) {
+      offset = updateTabsIndices(child.myTabs, offset);
+    }
+
+    doSaveUiState();
+  }
+
+  private static int updateTabsIndices(final JBRunnerTabs tabs, int offset) {
+    for (TabInfo each : tabs.getTabs()) {
+      final int index = tabs.getIndexOf(each);
+      final TabImpl tab = getTabFor(each);
+      if (tab != null) tab.setIndex(index + offset);
+    }
+    return offset + tabs.getTabCount();
+  }
+
+  private void doSaveUiState() {
+    if (isStateBeingRestored()) return;
+
     for (TabInfo each : myTabs.getTabs()) {
       GridImpl eachGrid = getGridFor(each);
       eachGrid.saveUiState();
     }
+
+    for (RunnerContentUi child : myChildren) {
+      child.doSaveUiState();
+    }
   }
 
   @Nullable
@@ -581,6 +858,17 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
     return getTabFor(info);
   }
 
+  @Override
+  public void showNotify() {
+    final Window window = SwingUtilities.getWindowAncestor(myComponent);
+    if (window instanceof IdeFrame.Child) {
+      ((IdeFrame.Child)window).setFrameTitle(mySessionName);
+    }
+  }
+
+  @Override
+  public void hideNotify() {}
+
   @Nullable
   private static TabImpl getTabFor(@Nullable final TabInfo tab) {
     if (tab == null) {
@@ -640,6 +928,10 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
     if (myComponent.getRootPane() != null) {
       saveUiState();
     }
+    if (myOriginal != null) {
+      myDisposing = true;
+      fireContentClosed(null);
+    }
   }
 
   public boolean canChangeSelectionTo(Content content, boolean implicit) {
@@ -674,14 +966,25 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
   }
 
   public void dispose() {
-
+    if (myOriginal != null) {
+      myOriginal.myChildren.remove(this);
+    }
   }
 
   public void restoreLayout() {
-    Content[] all = myManager.getContents();
+    final RunnerContentUi[] children = myChildren.toArray(new RunnerContentUi[myChildren.size()]);
+    final List<Content> contents = new ArrayList<Content>();
+    Collections.addAll(contents, myManager.getContents());
+    for (RunnerContentUi child : children) {
+      Collections.addAll(contents, child.myManager.getContents());
+    }
+    Content[] all = contents.toArray(new Content[contents.size()]);
 
     setStateIsBeingRestored(true, this);
     try {
+      for (RunnerContentUi child : children) {
+        child.myManager.removeAllContents(false);
+      }
       myManager.removeAllContents(false);
       myMinimizedViewActions.removeAll();
     }
@@ -730,7 +1033,7 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
   }
 
   public boolean isMinimizeActionEnabled() {
-    return myMinimizeActionEnabled;
+    return myMinimizeActionEnabled && myOriginal == null;
   }
 
   public boolean isMoveToGridActionEnabled() {
@@ -820,12 +1123,12 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
     public void addNotify() {
       super.addNotify();
 
-      if (!myUiLastStateWasRestored) {
+      if (!myUiLastStateWasRestored && myOriginal == null) {
         myUiLastStateWasRestored = true;
 
-        //noinspection SSBasedInspection
         // [kirillk] this is done later since restoreUiState doesn't work properly in the addNotify call chain
         //todo to investigate and to fix (may cause extra flickering)
+        //noinspection SSBasedInspection
         SwingUtilities.invokeLater(new Runnable() {
           public void run() {
             restoreLastUiState().doWhenDone(new Runnable() {
@@ -946,90 +1249,6 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
     updateTabsUI(false);
   }
 
-  private static boolean willBeEmptyOnRemove(GridImpl grid, List<Content> toRemove) {
-    List<Content> attachedToGrid = grid.getAttachedContents();
-    for (Content each : attachedToGrid) {
-      if (!toRemove.contains(each)) return false;
-    }
-
-    return true;
-  }
-
-
-  public CellTransform.Restore detach(final Content[] content) {
-    List<Content> contents = Arrays.asList(content);
-
-    for (Content each : content) {
-      GridImpl eachGrid = getGridFor(each, false);
-      if (willBeEmptyOnRemove(eachGrid, contents)) {
-        TabInfo info = myTabs.findInfo(eachGrid);
-        if (info != null) {
-          info.setHidden(true);
-        }
-      }
-    }
-
-    updateTabsUI(true);
-
-    return new CellTransform.Restore() {
-      public ActionCallback restoreInGrid() {
-        showHiddenTabs();
-        updateTabsUI(true);
-        return new ActionCallback.Done();
-      }
-    };
-  }
-
-  private void showHiddenTabs() {
-    List<TabInfo> tabs = myTabs.getTabs();
-    for (TabInfo eachInfos : tabs) {
-      GridImpl eachGrid = (GridImpl)eachInfos.getComponent();
-      if (!eachGrid.getAttachedContents().isEmpty()) {
-        eachInfos.setHidden(false);
-      }
-    }
-  }
-
-  public void moveToTab(final Content content) {
-    saveUiState();
-
-    setStateIsBeingRestored(true, this);
-    try {
-      myManager.removeContent(content, false);
-      getStateFor(content).assignTab(myLayoutSettings.createNewTab());
-      getStateFor(content).setPlaceInGrid(PlaceInGrid.center);
-      myManager.addContent(content);
-    }
-    finally {
-      setStateIsBeingRestored(false, this);
-    }
-
-    saveUiState();
-  }
-
-  public void moveToGrid(final Content content) {
-    saveUiState();
-
-    setStateIsBeingRestored(true, this);
-
-    try {
-      myManager.removeContent(content, false);
-      getStateFor(content).assignTab(myLayoutSettings.getDefaultTab());
-      getStateFor(content).setPlaceInGrid(myLayoutSettings.getDefaultGridPlace(content));
-      myManager.addContent(content);
-    }
-    finally {
-      setStateIsBeingRestored(false, this);
-    }
-
-    select(content, true).doWhenDone(new Runnable() {
-      public void run() {
-        saveUiState();
-      }
-    });
-  }
-
-
   public Project getProject() {
     return myProject;
   }
@@ -1055,7 +1274,7 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
   }
 
   public boolean isHorizontalToolbar() {
-    return myLayoutSettings.isToolbarHorizontal();
+    return false;
   }
 
   public ActionCallback select(final Content content, final boolean requestFocus) {
@@ -1068,18 +1287,12 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
 
 
     final ActionCallback result = new ActionCallback();
-    if (grid.isDetached(content)) {
-      if (requestFocus) {
+    myTabs.select(info, false).doWhenDone(new Runnable() {
+      public void run() {
         grid.select(content, requestFocus).notifyWhenDone(result);
       }
-    }
-    else {
-      myTabs.select(info, false).doWhenDone(new Runnable() {
-        public void run() {
-          grid.select(content, requestFocus).notifyWhenDone(result);
-        }
-      });
-    }
+    });
+
 
     return result;
   }
@@ -1233,4 +1446,142 @@ public class RunnerContentUi implements ContentUI, Disposable, CellTransform.Fac
 
     return result;
   }
+
+
+  private int findFreeWindow() {
+    int i;
+    for (i = 1; i < Integer.MAX_VALUE; i++) {
+      if (!isUsed(i)) {
+        return i;
+      }
+    }
+    return i;
+  }
+
+  private boolean isUsed(int i) {
+    for (RunnerContentUi child : myChildren) {
+      if (child.getWindow() == i) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private DockManagerImpl getDockManager() {
+    return (DockManagerImpl)DockManager.getInstance(myProject);
+  }
+  
+  class MyDragOutDelegate implements TabInfo.DragOutDelegate {
+    private DragSession mySession;
+
+    @Override
+    public void dragOutStarted(MouseEvent mouseEvent, TabInfo info) {
+      final JComponent component = info.getComponent();
+      final Content[] data = CONTENT_KEY.getData((DataProvider)component);
+      final List<Content> contents = Arrays.asList(data);
+
+      storeDefaultIndices(data);
+
+      final Dimension size = info.getComponent().getSize();
+      final Image image = myTabs.getComponentImage(info);
+      if (component instanceof Grid) {
+        info.setHidden(true);
+      }
+
+      Presentation presentation = new Presentation(info.getText());
+      presentation.setIcon(info.getIcon());
+      mySession = getDockManager().createDragSession(mouseEvent, new DockableGrid(image, presentation,
+                                                                                  size,
+                                                                                  contents, 0));
+    }
+
+    @Override
+    public void processDragOut(MouseEvent event, TabInfo source) {
+      mySession.process(event);
+    }
+
+    @Override
+    public void dragOutFinished(MouseEvent event, TabInfo source) {
+      final Component component = event.getComponent();
+      final IdeFrame window = UIUtil.getParentOfType(IdeFrame.class, component);
+      if (window != null) {
+        
+      }
+      mySession.process(event);
+      mySession = null;
+    }
+  }
+
+  class DockableGrid implements DockableContent<List<Content>> {
+    final Image myImg;
+    private Presentation myPresentation;
+    private final Dimension myPreferredSize;
+    private final List<Content> myContents;
+    private final int myWindow;
+
+    public DockableGrid(Image img, Presentation presentation, final Dimension size, List<Content> contents, int window) {
+      myImg = img;
+      myPresentation = presentation;
+      myPreferredSize = size;
+      myContents = contents;
+      myWindow = window;
+    }
+
+    @Override
+    public List<Content> getKey() {
+      return myContents;
+    }
+
+    @Override
+    public Image getPreviewImage() {
+      return myImg;
+    }
+
+    @Override
+    public Dimension getPreferredSize() {
+      return myPreferredSize;
+    }
+
+    @Override
+    public String getDockContainerType() {
+      return DockableGridContainerFactory.TYPE;
+    }
+
+    @Override
+    public Presentation getPresentation() {
+      return myPresentation;
+    }
+
+    public RunnerContentUi getRunnerUi() {
+      return RunnerContentUi.this;
+    }
+
+    public RunnerContentUi getOriginalRunnerUi() {
+      return myOriginal != null ? myOriginal : RunnerContentUi.this;
+    }
+
+    public List<Content> getContents() {
+      return myContents;
+    }
+
+    @Override
+    public void close() {
+    }
+
+    public int getWindow() {
+      return myWindow;
+    }
+  }
+
+  void fireContentOpened(Content content) {
+    for (Listener each : myDockingListeners) {
+      each.contentAdded(content);
+    }
+  }
+
+  void fireContentClosed(Content content) {
+    for (Listener each : myDockingListeners) {
+      each.contentRemoved(content);
+    }
+  }
 }
index 5cc040503267df15ae890d42ee942d844cab64d5..b336d791e5047d2b1cf40381e6513bdd719a169f 100644 (file)
@@ -20,6 +20,7 @@ import com.intellij.execution.ui.layout.LayoutAttractionPolicy;
 import com.intellij.execution.ui.layout.PlaceInGrid;
 import com.intellij.execution.ui.layout.Tab;
 import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Key;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.ui.content.Content;
@@ -33,7 +34,8 @@ import javax.swing.*;
 import java.util.*;
 
 public class RunnerLayout  {
-
+  public static final Key<Integer> DEFAULT_INDEX = Key.create("RunnerLayoutDefaultIndex");
+  public static final Key<Integer> DROP_INDEX = Key.create("RunnerLayoutDropIndex");  
   private final String myID;
 
   protected Map<String, ViewImpl> myViews = new HashMap<String, ViewImpl>();
@@ -64,10 +66,6 @@ public class RunnerLayout  {
     return tab;
   }
 
-  public TabImpl getDefaultTab() {
-    return getOrCreateTab(0);
-  }
-
   private TabImpl createNewTab(final int index) {
     final TabImpl tab;
 
@@ -153,7 +151,9 @@ public class RunnerLayout  {
     }
 
     for (TabImpl eachTab : myTabs) {
-      eachTab.write(parentNode);
+      if (isUsed(eachTab)) {
+        eachTab.write(parentNode);
+      }
     }
 
     parentNode.addContent(XmlSerializer.serialize(myGeneral));
@@ -166,13 +166,13 @@ public class RunnerLayout  {
     myViews.clear();
 
     for (TabImpl each : myTabs) {
-      final TabImpl.Default defaultTab = getOrCreateDefaultTab(each.getIndex());
+      final TabImpl.Default defaultTab = getOrCreateDefaultTab(each.getDefaultIndex());
       each.copyFrom(defaultTab);
     }
   }
 
   public boolean isToolbarHorizontal() {
-    return myGeneral.horizontalToolbar;
+    return false;
   }
 
   public void setToolbarHorizontal(boolean horizontal) {
index 268029f68165c1ff51099009964ee2a600464510..673c7bbe9898892dc5d1c456bdc1212f71e4fbaa 100644 (file)
@@ -40,6 +40,10 @@ public class TabImpl extends AbstractTab implements Tab {
     return myIndex;
   }
 
+  public int getDefaultIndex() {
+    return myDefaultIndex >= 0 ? myDefaultIndex : myIndex;
+  }
+
   public String getDisplayName() {
     return myDisplayName;
   }
@@ -52,6 +56,10 @@ public class TabImpl extends AbstractTab implements Tab {
     myIndex = index;
   }
 
+  public void setDefaultIndex(final int index) {
+    myDefaultIndex = index;
+  }
+
   public void setDisplayName(final String displayName) {
     myDisplayName = displayName;
   }
@@ -161,6 +169,7 @@ public class TabImpl extends AbstractTab implements Tab {
 
     public Default(final int index, final String displayName, final Icon icon) {
       myIndex = index;
+      myDefaultIndex = index;
       myDisplayName = displayName;
       myIcon = icon;
     }
index 13d0e593c255312aa4ed63b0fb626f2511894c76..84282337391b230eb87abda9bf450dd77083ac08 100644 (file)
 
 package com.intellij.execution.ui.layout.impl;
 
+import com.intellij.execution.ui.layout.GridCell;
 import com.intellij.execution.ui.layout.ViewContext;
 import com.intellij.openapi.actionSystem.ActionGroup;
+import com.intellij.openapi.util.ActionCallback;
 
 public interface ViewContextEx extends ViewContext {
   RunnerLayout getLayoutSettings();
 
   ActionGroup getCellPopupGroup(String place);
 
-  void doWhenInitialized(Runnable runnable);
+  boolean isOriginal();
+  
+  int getWindow();
 
+  ActionCallback detachTo(int window, GridCell cell);
 }
\ No newline at end of file
index 89673d9d600dcf8db7ce33bb22faa7f5b9852998..83b8d083382718f67823dab2381f0e0cd8c0cb97 100644 (file)
@@ -31,16 +31,19 @@ public class ViewImpl implements View {
 
   private Tab myTab;
   private int myTabIndex;
+  
+  private int myWindow;
 
   private PlaceInGrid myPlaceInGrid;
 
   private boolean myMinimizedInGrid;
 
-  public ViewImpl(String id, TabImpl tab, final PlaceInGrid placeInGrid, boolean minimizedInGrid) {
+  public ViewImpl(String id, TabImpl tab, final PlaceInGrid placeInGrid, boolean minimizedInGrid, int window) {
     myID = id;
     myTab = tab;
     myPlaceInGrid = placeInGrid;
     myMinimizedInGrid = minimizedInGrid;
+    myWindow = window;
   }
 
   public ViewImpl(RunnerLayout settings, Element element) {
@@ -94,6 +97,16 @@ public class ViewImpl implements View {
     myTabIndex = tabIndex;
   }
 
+  @Override
+  public int getWindow() {
+    return myWindow;
+  }
+
+  @Override
+  public void setWindow(int windowNumber) {
+    myWindow = windowNumber;
+  }
+
   public static class Default {
 
     private final String myID;
@@ -110,7 +123,7 @@ public class ViewImpl implements View {
 
     public ViewImpl createView(RunnerLayout settings) {
       final TabImpl tab = myTabID == Integer.MAX_VALUE ? settings.createNewTab() : settings.getOrCreateTab(myTabID);
-      return new ViewImpl(myID, tab, myPlaceInGrid, myMinimizedInGrid);
+      return new ViewImpl(myID, tab, myPlaceInGrid, myMinimizedInGrid, 0);
     }
 
     public PlaceInGrid getPlaceInGrid() {
index e60a8ccc09a79219cefe6a64f1127ed0a10756a2..52134b1f406ad94c563cb4cbcd375a1b0af4eb65 100644 (file)
@@ -32,6 +32,8 @@ import com.intellij.ui.ColoredListCellRenderer;
 import com.intellij.ui.SimpleTextAttributes;
 import com.intellij.ui.popup.list.ListPopupImpl;
 import com.intellij.util.Processor;
+import com.intellij.util.containers.hash.*;
+import com.intellij.util.containers.hash.HashSet;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -39,6 +41,7 @@ import javax.swing.*;
 import java.awt.*;
 import java.awt.event.ActionEvent;
 import java.util.*;
+import java.util.HashMap;
 import java.util.List;
 
 /**
@@ -207,7 +210,7 @@ public class GotoRelatedFileAction extends AnAction {
       }
     }
 
-    List<GotoRelatedItem> items = new ArrayList<GotoRelatedItem>();
+    Set<GotoRelatedItem> items = new HashSet<GotoRelatedItem> ();
 
     for (GotoRelatedProvider provider : Extensions.getExtensions(GotoRelatedProvider.EP_NAME)) {
       items.addAll(provider.getItems(contextElement));
@@ -215,7 +218,7 @@ public class GotoRelatedFileAction extends AnAction {
         items.addAll(provider.getItems(dataContext));
       }
     }
-    return items;
+    return new ArrayList<GotoRelatedItem>(items);
   }
 
   @Override
index 323560f5effffed911a717f785da17c72305ed7b..e39d357b7d34e71acb021cb973680d0fa0c10d60 100644 (file)
@@ -48,6 +48,7 @@ import java.io.File;
 import java.io.IOException;
 import java.net.URL;
 import java.text.MessageFormat;
+import java.text.SimpleDateFormat;
 import java.util.*;
 
 /**
@@ -319,10 +320,17 @@ public class FileTemplateManagerImpl extends FileTemplateManager implements Expo
     @NonNls Properties props = new Properties();
 
     Calendar calendar = Calendar.getInstance();
+    Date date = new Date(calendar.getTimeInMillis());
+    SimpleDateFormat sdfMonthNameShort = new SimpleDateFormat("MMM");
+    SimpleDateFormat sdfMonthNameFull = new SimpleDateFormat("MMMM");
+    SimpleDateFormat sdfYearFull = new SimpleDateFormat("yyyy");
+
     props.setProperty("DATE", DateFormatUtil.formatDate(calendar.getTime()));
     props.setProperty("TIME", DateFormatUtil.formatTime(calendar.getTime()));
-    props.setProperty("YEAR", Integer.toString(calendar.get(Calendar.YEAR)));
+    props.setProperty("YEAR", sdfYearFull.format(date));
     props.setProperty("MONTH", getCalendarValue(calendar, Calendar.MONTH));
+    props.setProperty("MONTH_NAME_SHORT", sdfMonthNameShort.format(date));
+    props.setProperty("MONTH_NAME_FULL", sdfMonthNameFull.format(date));
     props.setProperty("DAY", getCalendarValue(calendar, Calendar.DAY_OF_MONTH));
     props.setProperty("HOUR", getCalendarValue(calendar, Calendar.HOUR_OF_DAY));
     props.setProperty("MINUTE", getCalendarValue(calendar, Calendar.MINUTE));
index a0c783cfaf659c4f998c2f1ec6cd89c7013bdb7b..156ee77bd161479bd6bf82f81c57ab30722cae2f 100644 (file)
@@ -539,6 +539,7 @@ public abstract class TodoTreeBuilder extends AbstractTreeBuilder {
       return null;
     }
     Object[] children = getTreeStructure().getChildElements(parent);
+    Arrays.sort(children, getUi().getNodeDescriptorComparator());
     int idx = -1;
     for (int i = 0; i < children.length; i++) {
       if (obj.equals(children[i])) {
@@ -584,6 +585,7 @@ public abstract class TodoTreeBuilder extends AbstractTreeBuilder {
       return null;
     }
     Object[] children = getTreeStructure().getChildElements(parent);
+    Arrays.sort(children, getUi().getNodeDescriptorComparator());
     int idx = -1;
     for (int i = 0; i < children.length; i++) {
       if (obj.equals(children[i])) {
index 822ec3a804dcb6e3f41bec23ebce08f5645446c6..2285504fe806780f4143970c7227ef3c95b9a55b 100644 (file)
@@ -228,18 +228,20 @@ public class FileStructurePopup implements Disposable {
         for (ObjectWithWeight p : paths) {
           final Object last = ((TreePath)p.node).getLastPathComponent();
           final List<PsiElement> elements = new ArrayList<PsiElement>();
-          FilteringTreeStructure.FilteringNode node =
-            (FilteringTreeStructure.FilteringNode)((DefaultMutableTreeNode)last).getUserObject();
-          while (node != null) {
-            elements.add(getPsi(node));
-            node = node.getParentNode();
-          }
-          final int size = ContainerUtil.intersection(parents, elements).size();
-          if (size > max) {
-            max = size;
-            cur = p.node;
-          } else if (size == max && size == parents.size()) {
-            cur = p.node;
+          final Object object = ((DefaultMutableTreeNode)last).getUserObject();
+          if (object instanceof FilteringTreeStructure.FilteringNode) {
+            FilteringTreeStructure.FilteringNode node = (FilteringTreeStructure.FilteringNode)object;
+            while (node != null) {
+              elements.add(getPsi(node));
+              node = node.getParentNode();
+            }
+            final int size = ContainerUtil.intersection(parents, elements).size();
+            if (size > max) {
+              max = size;
+              cur = p.node;
+            } else if (size == max && size == parents.size()) {
+              cur = p.node;
+            }
           }
         }
 
index abaf63828b69bfff1d088def47745f2cbe268ac8..d7423c8420b21660119dffbdc594506a04a9cbd1 100644 (file)
@@ -19,7 +19,8 @@
  */
 package com.intellij.psi.stubs;
 
-import java.io.ByteArrayInputStream;
+import com.intellij.util.io.UnsyncByteArrayInputStream;
+
 import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
@@ -45,7 +46,7 @@ public class SerializedStubTree {
   }
 
   public StubElement getStub() {
-    return SerializationManager.getInstance().deserialize(new ByteArrayInputStream(myBytes));
+    return SerializationManager.getInstance().deserialize(new UnsyncByteArrayInputStream(myBytes));
   }
 
   public boolean equals(final Object that) {
index 6997d30dbed7e62450ecb97e0cd6769e4026e491..ced3ab62d05d315966c51a478ef3688562919e0a 100644 (file)
@@ -3570,6 +3570,10 @@ public class AbstractTreeUi {
     }
   }
 
+  public Comparator getNodeDescriptorComparator() {
+    return myNodeDescriptorComparator;
+  }
+
   private void disposeNode(DefaultMutableTreeNode node) {
     TreeNode parent = node.getParent();
     if (parent instanceof DefaultMutableTreeNode) {
index 91c23432ba70e06254e48fd337d4fe6e7a385c44..36ad4145c9e7188cabbee30924c5bb8794685436 100644 (file)
@@ -18,6 +18,8 @@ package com.intellij.notification;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.popup.Balloon;
+import com.intellij.openapi.ui.popup.JBPopupAdapter;
+import com.intellij.openapi.ui.popup.LightweightWindowEvent;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -97,6 +99,11 @@ public class Notification {
 
   public void expire() {
     NotificationsManager.getNotificationsManager().expire(this);
+    hideBalloon();
+    myExpired = true;
+  }
+
+  public void hideBalloon() {
     if (myBalloonRef != null) {
       final Balloon balloon = myBalloonRef.get();
       if (balloon != null) {
@@ -104,15 +111,20 @@ public class Notification {
       }
       myBalloonRef = null;
     }
-    myExpired = true;
   }
 
-  public void setBalloon(@Nullable final Balloon balloon) {
-    if (balloon != null) {
-      myBalloonRef = new WeakReference<Balloon>(balloon);
-    } else {
-      myBalloonRef = null;
-    }
+  public void setBalloon(@NotNull final Balloon balloon) {
+    hideBalloon();
+    myBalloonRef = new WeakReference<Balloon>(balloon);
+    balloon.addListener(new JBPopupAdapter() {
+      @Override
+      public void onClosed(LightweightWindowEvent event) {
+        WeakReference<Balloon> ref = myBalloonRef;
+        if (ref != null && ref.get() == balloon) {
+          myBalloonRef = null;
+        }
+      }
+    });
   }
 
   @Nullable
index d3fd4590a2459ff25f853bf58fea537c771b996a..e3993f86206d22f5f2b1e85698ea0d0d11953443 100644 (file)
@@ -272,6 +272,17 @@ public class TableScrollingUtil {
         moveEnd(list);
       }
     }.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0)), list);
+
+    new AnAction() {
+      public void actionPerformed(AnActionEvent e) {
+        moveHome(list);
+      }
+    }.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_HOME, 0)), list);
+    new AnAction() {
+      public void actionPerformed(AnActionEvent e) {
+        moveEnd(list);
+      }
+    }.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_END, 0)), list);
   }
 
 }
index f599a1d8bcd236760066a83036b7ca6f3b7ba247..25fb0289681322209015af5ef266af07e1897749 100644 (file)
@@ -30,7 +30,7 @@ public interface DockContainer extends Disposable, Activatable {
   RelativeRectangle getAcceptArea();
   boolean canAccept(DockableContent content, RelativePoint point);
 
-  JComponent getComponent();
+  JComponent getContainerComponent();
 
   void add(DockableContent content, RelativePoint dropTarget);